在弧线中,当你不合成时会发生什么

时间:2012-11-08 21:08:28

标签: objective-c ios automatic-ref-counting

在启用iOS ARC的项目中,当我不合成属性时会发生什么,因为不允许保留/释放?

@interface SomeClass : NSObject {
    NSMutableArray*     _pieces;
}
@end

在这种情况下,iVar _pieces的内存语义是什么? 假设我使用_pieces = whatever设置它。

当我的SomeClass实例被解除分配时,_pieces是否设置为nil? _pieces是否存储为弱引用? 如果保留_pieces的所有其他对象释放它,当我尝试访问它时它是否为null?

5 个答案:

答案 0 :(得分:16)

一些观察结果,其中很多观点可能基于其他人的反馈而明确:

  1. 您合成了属性,而不是实例变量,在您的示例中,您向我们展示了一个实例变量的示例,而不是属性。

  2. 您的问题可能意味着在合成和执行retain / release的能力之间存在一些假设的联系,但没有这样的联系。执行retainrelease的功能取决于您是否使用ARC。它与合成属性无关。

  3. 正如其他人所观察到的,默认情况下,显式声明的实例变量(例如您的示例)是strong引用。因此,在您的示例中,_piecesstrong引用。

  4. 是的,当您的SomeClass对象被取消分配时,它将删除对strong对象的_pieces引用。显然,如果这是_pieces指向的对象的最后一个强引用,它将被释放,并且您在其他地方使用的任何其他weak引用将被设置为nil。有关内存管理的更完整讨论,请参阅Apple的Advanced Memory Management Programming GuideTransitioning to ARC

  5. 您问“如果保留_pieces的所有其他对象都将其释放,那么当我尝试访问它时,它是nil吗?”显然,如果_piecesweak引用,那将是正确的,但鉴于它strong中隐含SomeClass引用,不,情况并非如此。

  6. 如果您想pieces成为declared property,则语法为
    @property (nonatomic, strong) NSMutableArray* pieces;

    strongweak(或其他)的约束决定了财产的记忆管理。

  7. 如果你声明一个属性,你不仅不再需要显式定义实例变量,而是现在建议你真的不应该这样做(因为当它被合成时,编译器将创建ivar为了你)。但是,如果您碰巧有一个显式声明的属性正确名称的实例变量,编译器将使用该属性。但这不仅是不必要的,而且也是不可取的(因为如果你错误输入实例变量的名称,你可能会在不知不觉中最终得到两个实例变量)。只需让编译器为您的属性合成您的实例变量,这种潜在的歧义就会消失。

  8. 将为属性合成的实例变量的名称由property implementation directive的语法控制,即@synthesize语句。因此,如果您对表单的@synthesize属性有pieces声明:

    @synthesize pieces;

    那么实例变量将被称为pieces。但是,如果您使用首选@synthesize语法:

    @synthesize pieces = _pieces;

    则实例变量名将具有前面的下划线(即约定,首选,以避免在属性和实例变量之间的代码中出现歧义)。并且,从Xcode 4.4开始,如果省略@synthesize的{​​{1}}语句,它将使用后一种语法隐式合成它,即实例变量将带有前导下划线。

答案 1 :(得分:3)

假设您尚未创建使用此属性的属性(覆盖假定的行为),ARC项目中的实例变量将被假定为强,因此声明确实是

@interface SomeClass : NSObject {
    __strong NSMutableArray* _pieces;
}
@end

所以,回答你的问题

  

当我的SomeClass实例被解除分配时,_pieces是否设置为nil?

不,但为其分配实例不会导致它被解除分配。

  

_pieces是否存储为弱引用?

不,这是一个很好的参考。

  

如果保留_pieces的所有其他对象都释放它,当我尝试访问它时它是否为空?

不,这与你的第一个问题相同。

答案 2 :(得分:2)

您是否声明了一个名为pieces的属性,或者这是一个直的ivar?

如果定义属性,则内存使用量取决于您定义属性的方式。

如果这是一个直的ivar,那么默认情况下,ivar将是strong。这实际上意味着ivar将正确地保留和释放您分配给它的对象。你可以安全地使用它而不必担心它。

答案 3 :(得分:0)

据我所知,ARC将以与strong类似的方式对待它。分配给它时,传入的值将为retain,不再指向的值将为release d。如果它以某种方式变得过度释放,它只会摇摆不定。如果您有财产声明,ARC将遵守其中指定的规则,并且将以@synthesize someObject = _someObject的形式自动为您合成访问者。当对象被释放时,我假设对象被发送release,这样如果没有其他东西断言所有权,指针所指向的对象也将被释放。

答案 4 :(得分:0)

使用新的运行时你只需要@properties btw - 不要声明ivars,不要合成