在界面中定义strong
属性时,如下所示:
@property (nonatomic, strong) UIColor *petColor;
不再需要添加@synthesize
或@dynamic
,或者手动将内部ivar定义为_petColor
,这一切都正常。自动生成setter / getter,您可以在内部访问_petColor
,无需任何其他代码。
然而,我对如何(如果有的话)在覆盖一个setter时有点困惑,ARC知道是否要插入retain / release调用,具体取决于属性是否为{{ 1}}或strong
?例如,如果我有两个属性:
weak
如果我想覆盖这些属性的setter,它们似乎几乎完全相同?
@property (nonatomic, strong) UIColor *petColor;
@property (nonatomic, weak) SomeClass *petDelegate;
这是对的吗?如果是这样,ARC会自动在这两个setter中插入正确的- (void)setPetColor:(UIColor *)theColor {
if (![theColor isEqual:petColor]) {
_petColor = theColor;
}
}
- (void)setPetDelegate:(SomeClass *)theDel {
if (theDel != petDelegate) {
_petDelegate = theDel;
}
}
调用,还是仅在retain/release
属性的重写setter中插入?
进一步: strong
属性 在这种情况下是否与weak
属性行为有关?
答案 0 :(得分:5)
它比那更简单。合成时,实例变量获得相应的限定符:
@implementation MyClass {
// this is what is added by the auto synthesize
UIColor * __strong _petColor;
SomeClass * __weak _petDelegate;
}
因此,当您使用自己的setter分配实例变量时,一切都很好,除了copy
限定符。那个不能用于实例变量,所以然后将副本分配给实例变量。
关于对象属性的assign
(或等价的unsafe_unretained
),实例变量只是一个指针,并被合成为
SomeClass * __unsafe_unretained _petDelegate;
因此,如果分配给属性的对象被释放,则指针不会像弱,而是设置为nil
,但指向解除分配对象之前所处的位置。这可能会导致崩溃。根据经验,如果您为iOS 5或更高版本编写代码,请始终在对象属性上使用weak
代替assign
或unsafe_unretained
。
答案 1 :(得分:1)
设置属性的strong
,weak
或assign
属性会告诉编译器底层数据的存储类。如果这是一个自动生成的iVar,那么它映射如下:
如果您不使用自动生成的iVar,那么您提供的任何数据都应符合这些存储类映射。
请参阅:Objective-C Automatic Reference Counting (ARC) : Property declarations