Objective c 基本内存管理混乱

Objective c 基本内存管理混乱,objective-c,memory-management,Objective C,Memory Management,我敢打赌,我可以通过阅读这里类似的帖子或通过谷歌搜索找到这个问题的答案,但我想直接“听到”它,因为这是我理解上的一个反常现象 问题是,我有一些以前的员工编写的代码,我看到很多某种类型的构造,对我来说很奇怪,我只想澄清什么是“对”和“错” 比如说 - (void) setWwanServiceId: (NSString *) newValue { [wwanServiceId autorelease]; wwanServiceId = [newValue copy]; } 这里的

我敢打赌,我可以通过阅读这里类似的帖子或通过谷歌搜索找到这个问题的答案,但我想直接“听到”它,因为这是我理解上的一个反常现象

问题是,我有一些以前的员工编写的代码,我看到很多某种类型的构造,对我来说很奇怪,我只想澄清什么是“对”和“错”

比如说

- (void) setWwanServiceId: (NSString *) newValue {
    [wwanServiceId autorelease];
    wwanServiceId = [newValue copy];
}
这里的
wwanServiceId
是类的
NSString
成员,对我来说这似乎是一种奇怪的方式。据我所知,它将首先在对象上放置一个
自动释放
,基本上说:“当这个对象似乎没有被使用时,为我释放它,我真的不在乎”,然后副本将增加保留计数+1。。。。wwanServiceId?还是新价值?我想是第一个

那么让我更加困惑的是,让我们快速浏览一下
wwanServiceId
-string的生命周期

基本上,如果我们接收到一个通知,那么将设置该值,该通知将从通知处理程序方法调用上述
-setWwanServiceId:
方法。除此之外,它将仅用于阅读,因此我们可以放心地说,它将在任何给定点:

  • 将自动释放放在对象上
  • 保留新的字符串副本
  • 还有一个怪癖,这就是我开始怀疑的地方,即在
    -dealoc
    方法中,它看起来像这样:

    - (void) dealloc {
        [[self wwanServiceId] release];
        [super dealloc];
    }
    
    [wwanServiceId release];
    
    那么那里发生了什么?它将发布
    wwanServiceId
    ,正如我所说的,它的内存管理唯一一次被触动(如果我没有错过任何东西,但我觉得非常确定的话),就是放一个自动释放并保留它

    因此,总结一下: 这里的想法是,他认为,因为他总是在放自动释放后保留一个新的副本,所以他需要在最后发布它。。或者这是我唯一能想到的。或者只是觉得在最后做一个额外的发布是安全的,以防万一

    因为据我所知,如果这个setter被调用一次,它将在将来放置一个
    自动释放(-1),执行
    保留(+1),当调用析构函数时,它将执行“最终释放”(-1)


    任何有助于我理解的想法或建议(如果事实上我是错的,并且内存处理是正确的)都将不胜感激。

    调试并查看

    [wwanServiceId autorelease];
    
    wwanServiceId有一个地址。这句话并没有改变它。但它确实会减少此对象的保留计数。 就这样

    wwanServiceId = [newValue copy];
    
    此语句创建一个新对象。新对象是newValue的副本。比较对象的地址,您将看到,wwanServiceId中的地址将不同于newValue的地址,也不同于wwanServiceId在语句执行之前的地址

    copy
    中隐含的retain将影响wwanServiceId,但它会影响刚刚使用
    copy
    创建的新对象。它不影响在之前的语句期间自动释放的wwanServiceId对象

    在执行完
    setWwanServiceId
    后的某个时刻,旧的自动删除对象将显示。(假设保留计数现在为0。如果由于其他原因或仅因错误而保留而大于0,则它将保留并可能导致泄漏。)

    一旦您理解了这一点,您就不会再质疑dealloc方法中发生了什么<代码>wwanServiceId
    已发布。这意味着其保留计数减少1。如果为0,则将自动解除分配。 你甚至可以在那里自动释放它。与自动释放的不同之处在于,在执行当前方法时,自动释放的对象仍然存在并且可用。它的发布将在稍后的某个时间点生效

    但是没有理由自动删除dealloc中的对象。
    在给出的示例中,甚至没有充分的理由自动释放setter
    setWwanServiceId
    中的对象。两种方法都可以直接释放对象

    调试一下,看一看

    [wwanServiceId autorelease];
    
    wwanServiceId有一个地址。这句话并没有改变它。但它确实会减少此对象的保留计数。 就这样

    wwanServiceId = [newValue copy];
    
    此语句创建一个新对象。新对象是newValue的副本。比较对象的地址,您将看到,wwanServiceId中的地址将不同于newValue的地址,也不同于wwanServiceId在语句执行之前的地址

    copy
    中隐含的retain将影响wwanServiceId,但它会影响刚刚使用
    copy
    创建的新对象。它不影响在之前的语句期间自动释放的wwanServiceId对象

    在执行完
    setWwanServiceId
    后的某个时刻,旧的自动删除对象将显示。(假设保留计数现在为0。如果由于其他原因或仅因错误而保留而大于0,则它将保留并可能导致泄漏。)

    一旦您理解了这一点,您就不会再质疑dealloc方法中发生了什么<代码>wwanServiceId
    已发布。这意味着其保留计数减少1。如果为0,则将自动解除分配。 你甚至可以在那里自动释放它。与自动释放的不同之处在于,在执行当前方法时,自动释放的对象仍然存在并且可用。它的发布将在稍后的某个时间点生效

    但是没有理由自动删除dealloc中的对象。 在给出的示例中,甚至没有充分的理由自动释放setter
    setWwanServiceId中的对象<
    
    [[self wwanServiceId] release];
    
    [wwanServiceId release];
    
    - (void) setWwanServiceId: (NSString *) newValue {
       [wwanServiceId autorelease];
       wwanServiceId = [newValue copy];
    }
    
    - (void) setWwanServiceId: (NSString *) newValue
    {
       NSString *oldValue = wwanServiceId;
       wwanServiceId = [newValue copy];
       [oldValue release];
    }