@interface SomeClass : NSObject {
NSMutableArray* _pieces;
}
@end
在这种情况下,iVar _pieces的内存语义是什么? 如果我使用
_pieces = whatever
进行设置,那么_piecesset是否为nil?
_piecesset是否存储为弱引用?
如果所有其他对象都释放了对_pieces的保留,当我尝试访问它时,它会变成null吗?@interface SomeClass : NSObject {
NSMutableArray* _pieces;
}
@end
_pieces = whatever
进行设置,那么_piecesset是否为nil?
_piecesset是否存储为弱引用?
如果所有其他对象都释放了对_pieces的保留,当我尝试访问它时,它会变成null吗?以下是一些观察,其中许多可能已经基于他人的反馈而变得清晰明了:
你需要合成属性,而不是实例变量。在你的例子中,你展示了一个实例变量的例子,而不是属性。
你的问题可能意味着在合成和能够执行 retain
/release
之间存在某种假定的联系,但实际上并没有这样的联系。能否执行 retain
和 release
取决于你是否使用 ARC。它与合成属性无关。
正如其他人所观察到的那样,明确声明的实例变量(例如你的例子)默认情况下是 strong
引用。因此,在你的例子中,_pieces
是一个 strong
引用。
当你的 SomeClass
对象被释放时,它将删除对 _pieces
对象的引用。显然,如果这是指向由 _pieces
指向的对象的最后一个强引用,则该对象将被释放,你在其他地方可能有的任何 weak
引用将被设置为 nil
。有关内存管理的更完整讨论,请参见 Apple 的 Advanced Memory Management Programming Guide 和 Transitioning to ARC。
你问道“如果所有其他已经对 _pieces
保留的对象都释放它了,我尝试访问它时它会是 nil
吗?”显然,如果 _pieces
是一个 weak
引用,那么这将是正确的,但是鉴于它在 SomeClass
中是隐式的一个强引用,所以不,不是这样的情况。
如果你想把 pieces
做成 declared property,语法应该是:@property (nonatomic, strong) NSMutableArray* pieces;
指定strong
还是weak
(或其他)取决于属性的内存管理。
如果你声明了一个属性,则你不再需要明确定义实例变量,而现在建议你确实不要这样做(因为当它被合成时,编译器将为你创建实例变量)。但是,如果你恰好有一个明确声明的与属性名称相同的实例变量,编译器将使用该变量作为属性。但这不仅是不必要的,而且是不可取的(因为如果你拼写实例变量的名称错误,可能会无意中得到两个实例变量)。让编译器为你的属性合成实例变量,这个潜在的歧义就消失了。
用于属性的实例变量的名称由 property implementation directive 的语法控制,即 @synthesize
语句。因此,如果你有一个形如@synthesize pieces;
的 @synthesize
语句,则实例变量将被称为 pieces
。但是,如果你使用首选的@synthesize pieces = _pieces;
语法,则实例变量名称将带有前导下划线(根据惯例,这被认为是首选的,以避免在代码中出现属性和实例变量之间的歧义)。从 Xcode 4.4 开始,
@private
指令),但我认为将私有内容放在类扩展中更加清晰。 - Rob@interface SomeClass : NSObject {
__strong NSMutableArray* _pieces;
}
@end
所以,针对你的问题回答如下:
当我的SomeClass实例被释放时,_pieces是否置为nil?
不会,但将实例分配给它也不会导致其被释放。
_pieces是作为弱引用存储的吗?
不是,它是一个强引用。
如果所有其他保留了_pieces的对象都释放了它,那么当我尝试访问它时,它会变成null吗?
不会,这与您的第一个问题相同。
_pieces
所指向的对象。它是由变量引用的对象,当该变量被释放时,对象会跟踪引用它的内容(保留计数)。如果一个强引用变量引用了一个对象,则保留计数会增加。如果该对象不再被特定变量引用,则保留计数会减少。一旦保留计数为0,就可以将其释放。 - WDUK你是在声明一个名为pieces
的属性,还是直接使用了ivar?
如果你定义了一个属性,那么内存使用情况取决于你如何定义该属性。
如果这是一个直接的ivar,则默认情况下ivar将是strong
。这基本上意味着ivar将正确地保留和释放你分配给它的任何对象。你可以放心使用它而不必担心。
retain
,而不再指向的值将被release
。只有在某种情况下过度释放了它,它才会悬空。如果你有一个属性声明,ARC 将遵守其中指定的规则,并且访问器将以@synthesize someObject = _someObject
的形式自动合成。当对象被释放时,我认为对象会被发送release
,因此如果没有其他东西断言拥有权,则指针指向的对象也将被释放。使用新的运行时,你只需要使用 @properties - 不要声明 ivars,也不要合成