8

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

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

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

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

4

5 回答 5

16

一些观察,根据其他人的反馈,其中大部分可能很清楚:

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

  2. retain您的问题可能暗示合成和执行/的能力之间存在某种假定的联系release,但没有这种联系。retain做事的能力release是你是否使用ARC的函数。它与综合属性无关。

  3. 正如其他人所观察到的,默认情况下,显式声明的实例变量(例如您的示例)是strong引用。所以,在你的例子中,_pieces是一个strong参考。

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

  5. 你问“如果所有其他保留的对象都_pieces释放它,nil我会在尝试访问它时释放它吗?” 显然,如果_pieces是一个weak引用,那将是正确的,但鉴于它隐含地是一个strong引用SomeClass,不,事实并非如此。

  6. 如果您想创建pieces一个声明的属性,则语法将是vs. (或其他)

    @property (nonatomic, strong) NSMutableArray* pieces;

    的指定指示属性的内存管理。strongweak

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

  8. 将为属性合成的实例变量的名称由属性实现指令的语法(即@synthesize语句)控制。因此,如果您对表单的属性有一个@synthesize声明:那么实例变量将被调用。但是,如果您使用首选语法:则实例变量名称将具有前面的下划线(按照惯例,这是首选语法,以避免代码中属性和实例变量之间的歧义)。而且,从 Xcode 4.4 开始,如果您省略a 的语句,它将使用后一种语法为您隐式合成它,即实例变量将带有前导下划线)。pieces

    @synthesize pieces;

    pieces@synthesize

    @synthesize pieces = _pieces;

    @synthesize@property

于 2012-11-09T09:04:51.800 回答
3

假设你没有创建一个使用它的属性,它覆盖了假定的行为,ARC项目中的实例变量被假定为强的,所以声明真的是

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

所以,回答你的问题

当我的 SomeClass 的实例被释放时,_pieces 是否设置为 nil?

不,但是为它分配一个实例不会导致它被释放。

_pieces 是否存储为弱引用?

不,这是一个强有力的参考。

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

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

于 2012-11-08T21:13:20.483 回答
2

您是在声明一个名为的属性pieces,还是这是一个直接的 ivar?

如果您定义一个属性,那么内存使用量取决于您如何定义该属性。

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

于 2012-11-08T21:13:00.827 回答
0

据我所知,ARC 会像对待它一样对待它,就像对待它一样strong。当您分配给它时,传入的值将被retained 并且不再指向的值将是released。只有当它以某种方式过度释放时,它才会悬挂。如果你有一个属性声明,ARC 会遵守那里指定的规则,访问器会自动合成为你的表单@synthesize someObject = _someObject。当对象被释放时,我假设对象被发送release,这样如果没有其他东西断言所有权,指针指向的对象也将被释放。

于 2012-11-08T21:17:58.327 回答
0

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

于 2012-11-08T21:31:12.197 回答