【问题标题】:iPhone Memory release issueiPhone 内存释放问题
【发布时间】: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 返回的内容。有关更多说明,请参阅stackoverflow.com/questions/1087689/…。我建议不要在 init 和 dealloc 中使用点符号。
  • 顺便说一下,您使用可变对象作为属性。这个stackoverflow.com/questions/816720/… 可能会有所帮助。

标签: iphone


【解决方案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 是正确的。
            猜你喜欢
            • 2010-10-03
            • 1970-01-01
            • 1970-01-01
            • 2011-02-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多