【问题标题】:Clarification on when to release pointers after allocating澄清分配后何时释放指针
【发布时间】:2011-10-12 23:56:44
【问题描述】:

在我的最后一个问题 (here) 中,我遇到了一个问题,即我得到一个 EXC_BAD_ACCESS,因为我正在释放我刚刚分配的变量:

NSMutableArray* s = [[NSMutableArray alloc] init];
stack = s;
[s release];

应该是

NSMutableArray* s = [[NSMutableArray alloc] init];
stack = s;

但是,堆栈是我班级的保留属性。它是这样声明的:

@interface StateStack ()
@property (nonatomic, retain) NSMutableArray* stack;
@end

我的印象是,当您分配“保留”变量时,它会自动增加对象的 retainCount。所以你应该首先释放你的指针(如here)。

为什么这两种情况不同?谢谢!

【问题讨论】:

标签: objective-c memory-management retain


【解决方案1】:

因为您必须分配属性,而不是实例变量。当您分配给该属性时,它将再次保留该变量,然后您就不会遇到问题。你的代码应该是这样的:

NSMutableArray* s = [[NSMutableArray alloc] init];
self.stack = s;
[s release];

这样你不是分配给变量,而是使用属性(实际上是一种方法)。如果您在这种情况下没有释放,那么您的代码中就会出现内存泄漏。

当您执行 stack = s 时,您将直接分配给实例变量,并且该数组从未保留。

【讨论】:

    【解决方案2】:

    没有“保留变量”之类的东西。这是一个保留 property — 意味着属性后面的 setter 方法保留新值并释放旧值。但是分配给变量只是分配。事实上,人们通常建议直接分配给init 中的实例变量的原因是特别是它不会通过setter,因为可以想象setter 可能会在init 中产生你不想要的副作用(当您的对象尚未完全构建)。

    注意:我在这里谈论的是普通的内存管理规则。如果您使用 ARC,这一切都不同。但我想如果你是的话,你会提到的。

    【讨论】:

    • 感谢有关在 init 中直接分配给实例变量的提示,我不知道
    【解决方案3】:

    self.stackstack 是两个完全不同的东西。当您使用stack 时,您访问的是实例变量,而不是属性。这意味着不会调用您的访问器方法,这意味着不会使用自动内存管理。这就是为什么你不应该在你的例子中释放s

    如果您改用self.stack,那么您将使用属性。编译器将self.stack = value[self setStack:value] 完全相同,self.stack[self stack] 完全相同。由于正在使用访问器,内存管理将与您定义属性的方式相匹配,并且您应该在分配后释放一个值。

    【讨论】:

      【解决方案4】:

      毛里西奥有正确的答案:一定要分配给财产以获得@property 的好处。为了稍微澄清这一点,请尝试使用如下代码:

      @interface StateStack : NSObject {
          NSArray *_stack;
      }
      @property (nonatomic,retain) NSMutableArray *stack;
      @end
      
      @implementation StateStack
      @synthesize stack=_stack;
      @end
      

      现在,如果你尝试:

      NSMutableArray* s = [[NSMutableArray alloc] init];
      stack = s;
      [s release];
      

      您会收到一个错误,这意味着您尝试设置 ivar 而不是按预期设置属性。 ivar 名称和属性名称之间的这种不匹配违反了 Apple 的建议,但它是帮助您养成使用属性分配的习惯的好方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 1970-01-01
        • 2018-09-30
        • 2015-12-20
        • 2019-03-13
        相关资源
        最近更新 更多