iPhone 内存释放问题

Posted

技术标签:

【中文标题】iPhone 内存释放问题【英文标题】:iPhone Memory release issue 【发布时间】:2010-01-11 09:05:17 【问题描述】:

我对 iPhone 程序中的 dealloc 函数有一些疑问。是否需要给 [self.object_name release] 或 [object_name release] 可以吗?.. 我的dealloc函数中有这个奇怪的问题是这样的。

-(void) dealloc 
   [self.listOfDates release];
   [self.listOfDescriptions release];
   [super dealloc];
 

但程序崩溃并给出 EXEC_BAD_ACCESS。这里两个对象都是 NSMutableArray 实例,在类的 init 函数中分配了 alloc。没有 self 的相同功能可以正常工作,即

-(void) dealloc 
    [listOfDates release];
    [listOfDescription release];
    [super dealloc];
 

这是我声明属性的方式

@property (nonatomic,retain) NSMutableArray *listOfDates;
@property (nonatomic,retain) NSMutableArray *listOfDescription;

在实现文件中我对它进行了 sysnthesized,在 init 函数中我已经像这样分配了这些变量

self.listOfDates = [[NSMutableArray alloc] init];
self.listOfDescription = [[NSMutableArray alloc] init];

所以需要给 self 吗?我在这里错过了什么?

当我删除 mutableCopy 函数时问题已解决,该函数用于复制 NSMutableArrays 实例,该实例作为参数传递给 init 函数,如下所示

-(id)initWithDate:(NSMutableArray *)dates andDescription:(NSMutableArray*)descriptions

    if(self = [super initWithNibName:@"DateDescriptionControl" bundle:nil])
    
        self.listOfDates = [[NSMutableArray alloc] init];
        self.listOfDescription = [[NSMutableArray alloc] init];

        self.listOfDates = [dates mutableCopy];
        self.listOfDescription = [description mutableCopy]; 

    

   return self;

删除 mutableCopy 后,dealloc 现在不会抛出 EXEC_BAD_ACCESS。所以我在哪里犯了我仍然无法弄清楚的错误:(

【问题讨论】:

是类的 listOfDates 和 listOfDescription 属性吗? 是的,它是具有非原子和保留类的属性 你不应该在这里使用self. 在 initWithDate, self.listOfDates = [dates mutableCopy];会导致内存泄漏。您需要释放 mutableCopy 返回的内容。有关更多说明,请参阅***.com/questions/1087689/…。我建议不要在 init 和 dealloc 中使用点符号。 顺便说一下,您使用可变对象作为属性。这个***.com/questions/816720/… 可能会有所帮助。 【参考方案1】:

在 dealloc 函数中释放不需要 self 。

【讨论】:

【参考方案2】:

在 dealloc 中你有两个选择:

[foobar release];

self.foobar = nil;

第二个相当于写[self setFoobar:nil],它在setFoobar: 方法中是释放前一个值的地方(假设属性被定义为使用保留或复制)。我更喜欢第一种形式,您只需将release 直接发送到对象,但两者都可以。

编写[self.foobar release] 在技术上应该没问题,但如果您稍后调用self.foobar = nil,该对象将被第二次释放(并导致 EXC_BAD_ACCESS)。

【讨论】:

【参考方案3】:

self.something 表示[self something],因为点表示属性语法。你要的是self->something

【讨论】:

self->something 有效但不必要且奇怪。 如果提问者想保留self,这是最小的变化。当然,问题中的第二个代码是首选。【参考方案4】:

是的,

[对象释放];

应该可以正常工作。

【讨论】:

【参考方案5】:

您遇到的基本问题是由以下代码引起的:

self.listOfDates = [[NSMutableArray alloc] init];

当一个属性是“保留”并且您通过设置器访问它时,分配给它的对象应该在自动释放池中,如下所示:

self.listOfDates = [[[NSMutableArray alloc] init] autorelease];

但是,这有点难看,而 NSMutableArray 提供了一个很好的构造函数,可以自动为您执行此操作:

self.listOfDates = [NSMutableArray array];

您的代码未使用 ARC,因此该对象应位于自动释放池中。如果您使用的是 ARC,那么规则会有所不同。

【讨论】:

【参考方案6】:

最佳实践(非 ARC)。 在您的界面中声明 Varibal,如下所示

NSMutableArray *_listOfDates;
NSMutableArray *_listOfDescription;

你的二传手应该在下面。 (和你的代码一样)

@property (nonatomic,retain) NSMutableArray *listOfDates;
@property (nonatomic,retain) NSMutableArray *listOfDescription;

在你的实现中

@synthesize listOfDates = _listOfDates, listOfDescription = _listOfDescription;

初始化中

-(id)initWithDate:(NSMutableArray *)dates andDescription:(NSMutableArray*)descriptions

    if(self = [super initWithNibName:@"DateDescriptionControl" bundle:nil])
    
        NSMutableArray *tempListOfDates = [[NSMutableArray alloc] init];
        self.listOfDates = tempListOfDates;
        [tempListOfDates release];

        NSMutableArray *tempListOfDescription = [[NSMutableArray alloc] init];
        self.listOfDescription = tempListOfDescription;
        [tempListOfDescription release];
    

在释放中

-(void) dealloc 
    [_listOfDates release];
    [_listOfDescription release];
    [super dealloc];
 

【讨论】:

【参考方案7】:

只需使用 [object release] 释放实例变量。不需要使用“self”。

【讨论】:

我不知道为什么他的回答被否决了。您不应该在 dealloc 中使用访问器(self.)。直型苹果。 developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/…。也许你投了他的票是因为他说“没有必要”而不是“不推荐”,但从表面上看,benzado 是不正确的,futureelite 是正确的。

以上是关于iPhone 内存释放问题的主要内容,如果未能解决你的问题,请参考以下文章

内存泄漏与自动释放的字符串 iphone

iPhone:关于 NSAutoreleasePool 的困惑

iphone:如何解决这个内存泄漏?

iphone:多次自动释放对象

内存警告后释放 UIImage 时崩溃

iPhone 开发 - 释放一个自动释放的对象