4

在接口中定义strong属性时,如下所示:

@property (nonatomic, strong) UIColor *petColor;

不再需要添加@synthesize, 或@dynamic, 或手动将内部 ivar 定义为_petColor, 这一切都行得通。setter/getter 是自动生成的,您_petColor无需任何额外代码即可在内部访问。

但是,我有点困惑(如果有的话),当覆盖一个 setter 时,ARC 知道是否根据属性是strong还是插入保留/释放调用weak?例如,如果我有两个属性:

@property (nonatomic, strong) UIColor *petColor;
@property (nonatomic, weak) SomeClass *petDelegate;

如果我想覆盖这些属性的设置器,它们似乎几乎完全相同?

- (void)setPetColor:(UIColor *)theColor {
    if (![theColor isEqual:petColor]) {
        _petColor = theColor;
    }
}

- (void)setPetDelegate:(SomeClass *)theDel {
    if (theDel != petDelegate) {
        _petDelegate = theDel;
    }
}

它是否正确?如果是这样,ARC 是自动retain/release在这两个设置器中插入正确的调用,还是仅在strong属性的覆盖设置器中插入正确的调用?

进一步:在这种情况下,财产行为是否与weak财产行为不同assign

4

2 回答 2

5

它甚至比这更简单。综合时,实例变量获得各自的限定符:

@implementation MyClass {
    // this is what is added by the auto synthesize
    UIColor * __strong _petColor;
    SomeClass * __weak _petDelegate;
}

因此,当您使用自己的设置器分配给实例变量时,一切都很好,除了copy限定符。那个不能用于实例变量,因此将副本分配给实例变量。

关于对象属性assign(或等价物unsafe_unretained),实例变量只是一个指针,并被合成为

    SomeClass * __unsafe_unretained _petDelegate;

因此,如果分配给该属性的对象被释放,则指针不会nil像弱一样被设置为,而是指向被释放对象之前所在的位置。这可能会导致崩溃。根据经验,如果您为 iOS 5 或更高版本编写代码,请始终在对象属性上使用weak代替assign或。unsafe_unretained

于 2013-09-19T12:30:04.667 回答
1

设置属性的strongweakassign属性会告诉编译器底层数据的存储类。如果这是一个自动生成的 iVar,那么它的映射如下:

  • 强 -> __strong
  • 弱-> __弱
  • 分配-> __unsafe_unretained

如果您不使用自动生成的 iVar,那么您提供给属性的任何数据都应该符合那些存储类映射。

请参阅:Objective-C 自动引用计数 (ARC):属性声明

于 2013-09-19T12:40:24.183 回答