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

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

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

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

最佳答案

根据其他人的反馈,到现在为止,有几个观察结果可能很清楚:

  • 您综合了属性,而不是实例变量,并且在您的示例中,您向我们展示了实例变量(而不是属性)的示例。
  • 您的问题可能暗示合成和执行retain/release的能力之间存在某些假定的联系,但没有这种联系。进行retainrelease的能力取决于您是否使用ARC。它与合成属性无关。
  • 正如其他人所观察到的那样,默认情况下,显式声明的实例变量(例如您的示例)是strong引用。因此,在您的示例中,_piecesstrong引用。
  • 是的,当您的SomeClass对象被释放时,它将删除其对strong对象的_pieces引用。显然,如果这是对_pieces指向的对象的最后一个强引用,它将被释放,并且您在其他地方对它的任何其他weak引用都将被设置为nil。有关内存管理的更完整讨论,请参阅Apple的Advanced Memory Management Programming GuideTransitioning to ARC
  • 您询问“如果保留了_pieces的所有其他对象都将其释放,那么当我尝试访问它时,它是否会是nil?”显然,如果_piecesweak引用,那将是正确的,但是鉴于它在strong中隐式是SomeClass引用,不,不是这样。
  • 如果您想将pieces设置为declared property,则语法将为@property (nonatomic, strong) NSMutableArray* pieces;strongweak(或其他名称)的区别决定了属性的内存管理。
  • 如果您声明一个属性,则不仅不再必须显式定义实例变量,而且现在建议您不要这样做(因为当它被合成时,编译器将为您创建ivar)。但是,如果恰好有一个为属性正确命名的实例变量,编译器将使用该变量作为属性。但这不仅是不必要的,而且也是不可取的(因为如果您键入实例变量的名称,则可能会不经意地以两个实例变量结尾)。只要让编译器为属性综合实例变量,这种潜在的歧义就会消失。
  • 将为属性综合的实例变量的名称由property implementation directive的语法(即@synthesize语句)控制。因此,如果您的@synthesize属性具有pieces语句,其形式为:@synthesize pieces;,则实例变量将称为pieces。但是,如果您使用首选的@synthesize语法:@synthesize pieces = _pieces;,则实例变量名将带有下划线(按照惯例,这是首选,以避免代码在属性和实例变量之间产生歧义)。并且,从Xcode 4.4开始,如果您省略@synthesize@property语句,它将使用后一种语法为您隐式合成它,即实例变量将带有前导下划线)。
  • 关于objective-c - 在弧中,当您不进行合成时会发生什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13297829/

    10-09 09:14