我已经阅读了一些关于此的帖子,但还有一件事对我来说不太清楚。我知道这可能是一个n00b问题,但实际上我还没有完全掌握这个基本问题。我猜是自学的一个症状。
您在标题中声明了一个变量,如下所示:
@interface SomeClass : NSObject {
NSMutableArray *anArray;
}
@property (nonatomic, retain) NSMutableArray *anArray;
end
然后在您的主文件中,您将其合成并将其设置为初始值:
@implementation SomeClass
@synthesize anArray
- (SomeClass *)init{
if (self = [super init]) {
self.anArray = [[NSMutableArray alloc] initWithCapacity:10];
}
[return self];
并在你的课程deallocs时发布它:
- (void)dealloc {
[anArray release];
[super dealloc];
}
现在,当我运行乐器时,行
self.anArray = [[NSMutableArray alloc] initWithCapacity:10];
被识别为内存泄漏。这是一个内存泄漏,因为当你在头文件中定义变量anArray时它会分配内存吗? (因为我认为它是一个空指针。)因此,当你想初始化它,并调用[[NSMutableArray alloc] initWithCapacity:10]时,你正在重新分配内存,并丢失指向原始分配的指针?
相反,我使用了便捷类方法:
@implementation SomeClass
@synthesize anArray
- (SomeClass *)init{
if (self = [super init]) {
self.anArray = [NSMutableArray arrayWithCapacity:10];
}
[return self];
这不再被识别为仪器中的内存泄漏。由于这是一种方便的方法,anArray是自动释放的。但是,如果我假设标头中的实例声明分配内存,这将解释前一个问题,那么我是否还应该释放anArray?以这种方式设置初始值是否会保留它?
我理解
之间的区别NSMutableArray *anArray = [[NSMutableArray alloc] initWithCapacity:10];
和
NSMutableArray *anArray = [NSMutableArray arrayWithCapactiy:10];
但是我不确定我理解的是你在标题中声明了NSMutableArray * anArray,你应该使用哪两种方法以及为什么。无论你是否使用第二种方法,你应该在调用dealloc时释放anArray。
我可能会补充一点,我发现以下帖子/链接很有用:
答案 0 :(得分:3)
分配一个对象,引用计数为1。 设置具有“retain”属性的属性也会增加引用计数。
所以,这意味着这通常很糟糕:
@property (nonatomic, retain) Object * variable;
...
self.variable = [[Object alloc] init];
因为变量现在的引用计数为2。
设置对象的成员变量时,只需执行以下操作:
variable = [[Object alloc] init];
您还应该意识到这是有效的
self.anArray = [NSMutableArray arrayWithCapacity:10];
因为“arrayWithCapacity”(以及其他类似因子方法)自动释放它返回的对象,所以在设置属性后,它的引用计数基本上为1.
答案 1 :(得分:2)
这不是分配内存的实例。您可以假设在Objective-C中(至少在所有基于Apple的操作系统上),新初始化的类将其所有ivars设置为0(或者适当地为nil或NULL)。
您遇到的问题是您在初始化时使用的是属性,而不是ivar。由于您将属性声明为 retain ,因此使用属性访问器设置它会自动保留它。
因此,当你初始化时,要么必须取得所有权并直接设置ivar,要么就像你正在做的那样并使用属性访问器设置属性然后放弃init方法中的所有权(通过释放对象)你拥有或者像在第二个实例中那样使用便利构造函数,以便你永远不拥有返回的实例。
所以请记住,如果您使用属性访问器,即使在类本身内,您也将获得在属性上设置的功能(例如,非原子,保留等)。只要执行以下操作之一,就可以使用属性访问器:
// in these cases the property takes ownership through the
// retain keyword, so you must not take ownership yourself
self.anArray = something;
[self setAnArray:something];
[self setValue:something forKey:@"anArray"];
您可以直接访问您的ivar:
anArray = something; // in this case you must take ownership