Objective c 初始值设定项和副本

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

我刚刚读了一篇来自about的短文。我现在的问题是,传递给赋给实例变量的初始值设定项的参数是否总是使用
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你回答得很好,但这不是我真正问的问题!话虽如此,我认为否决票可能有点苛刻,但不幸的是,除非你修改你的答案,否则我的投票现在被锁定。