Objective c 初始值设定项和副本
我刚刚读了一篇来自about的短文。我现在的问题是,传递给赋给实例变量的初始值设定项的参数是否总是使用Objective c 初始值设定项和副本,objective-c,automatic-ref-counting,Objective C,Automatic Ref Counting,我刚刚读了一篇来自about的短文。我现在的问题是,传递给赋给实例变量的初始值设定项的参数是否总是使用copy?还是取决于实例变量的类型 #import "MyObject.h" @implementation MyObject { SomeType *_ivar1; SomeOtherType *_ivar2; } -(id)initWithParam1:(SomeType *)param1 andParam2:(SomeOtherType *)param2 { i
copy
?还是取决于实例变量的类型
#import "MyObject.h"
@implementation MyObject {
SomeType *_ivar1;
SomeOtherType *_ivar2;
}
-(id)initWithParam1:(SomeType *)param1 andParam2:(SomeOtherType *)param2
{
if ((self == [super init])) {
_ivar1 = [param1 copy]; // Always good
_ivar2 = [param2 copy]; // practice?
}
return self;
}
@end
我认为理解这篇文章的关键在于这句话: 因为我认为在-init期间使用访问器是个坏主意,
@属性定义的复制语义从来没有被使用过,ARC很乐意保留引用而不是复制它
我认为克雷格是在具体谈论以下案例:
@interface MyObject : NSObject {
SomeType *_ivar1;
}
-(id)initWithParam1:(SomeType *)param1;
@property (copy, nonatomic) SomeType* prop1;
@end
@implementation MyObject
@synthesize prop1 = _ivar1;
-(id)initWithParam1:(SomeType *)param1 {
if ((self == [super init])) {
/*
Craig could have called
self.prop1 = param1;
but he believes that it's a bad idea to call accessors
from the initializer, so he calls copy explicitly.
*/
_ivar1 = [param1 copy];
}
return self;
}
@end
取决于变量的类型和意图
对于简单类型--NSString、NSArray、NSNumber等--使用copy是因为您通常希望存储的类型是不可变的。也就是说,如果有一个firstName
属性,外部的东西可以通过传入NSMutableString
的实例来修改它,这是没有意义的
对于更复杂的类(封装状态和功能的类),通常不希望完全复制它,因为状态可能会随着时间的推移而改变。例如,如果您的应用程序是一个流媒体视频应用程序,其中有一个VideoPlayer实例,该实例播放封装在StreamingVideo实例中的视频,则您不希望复制StreamingVideo,因为随着下载更多数据(或发生错误),其内部状态将不断变化
也就是说,copy
在您希望状态的不可变快照时使用,并且在您希望对象a连接到B以更改/监视/查询B的状态时使用引用
是的,你希望它是一致的。如果属性是copy
,并且您有一个方便的初始值设定项来设置该属性,确保便利初始值设定项也复制属性设置的任何内容。在我看来,Craig只是警告为具有copy
说明符的属性设置backing ivar。我的一般规则是:如果存储的类型具有可变子类,则应该使用copy(对于属性和init).@JohnTopley你能解释一下你投反对票的原因吗?@dasbliklight你回答得很好,但这不是我真正问的问题!话虽如此,我认为否决票可能有点苛刻,但不幸的是,除非你修改你的答案,否则我的投票现在被锁定。