我遇到了一个与iphone内存管理有关的奇怪问题。
我通过一个例子来解释它 考虑下面写的一段代码
XMLParser.h中的
@interface XMLParser:NSObject/*<NSXMLParserDelegate>*/ {
NSMutableArray *parsedXML;
}
@property (nonatomic, retain) NSMutableArray *parsedXML;
在XMLParser.m中,如果我写下我的init函数,如下面的书面形式 #import“XMLParser.h”
@implementation XMLParser
@synthesize parsedXML;
- (XMLParser *) initXMLParser :(NSString *)repetingTagStr{
self = [super init];
if(self){
self.parsedXML = [[NSMutableArray alloc] initWithCapacity:1];
NSLog(@"%d", [self.parsedXML retainCount]);
[self.parsedXML release];
}
return self;
}
- (void) dealloc {
[parsedXML release];
[super dealloc];
}
@end
NSLog将保留计数设置为2,如果我尝试使用它,则在发布语句之后,它会导致崩溃。
现在如果我使用它分配它 NSMutableArray * temp = [[[NSMutableArray alloc] initWithCapacity:1] autorelease]; 要么 self.parsedXML = [NSMutableArray arrayWithCapacity:1]; 然后它运作正常。
我现在真的很困惑,因为自动释放不会导致崩溃和立即释放导致它崩溃。 是否与访问器方法有关。 请解释我的概念在内存管理方面失败的地方:)
答案 0 :(得分:1)
由于您已将自己的财产声明为(assign)
,因此当您设置self.parsedXML = ...
时,系统不会自动保留该属性。请尝试使用(retain)
属性。
答案 1 :(得分:1)
永远不要依赖来自retainCount的结果。 see here for more details
让我们考虑你的例子。您创建了一个NSMutableArray实例,并且由于您的访问器方法的定义,它直接分配给您的成员变量。保留计数仍保持为1,因为在创建时此计数器设置为1并且分配不会增加它。然后你释放你的阵列。保留计数降至0,您的阵列将被发送到必杀技。发布后访问您的阵列会使您的应用程序崩溃,这是您已经认识到的。
在使用自动释放创建NSMutableArray时(两个显示的示例都这样做),数组的保留计数器仍为1.但不立即发送释放。它在事件循环的当前迭代之后发送。这就是为什么你可以在方法中访问数组的原因。
我的建议:使用您的第一种方法并在创建数组后删除您的版本。在dealloc-method中你已经释放了你的数组,所以不会发生内存泄漏,一切都很好。
答案 2 :(得分:1)
首先,忽略retainCount - 我不能强调这一点!
您发布的代码(属性设置为retain
)不会崩溃。它必须是导致您错误的其他因素:)
添加崩溃的代码行,我们可以提供更多帮助。