使用alloc/retain/release的可能方案?

sha*_*der 2 memory-management objective-c retain

我已经使用ojective近一个星期了,我主要是一个c ++编码器.在我阅读了Apple的内存管理指南之后,我尝试将c ++中的内存使用方式带入目标c ...我试图总结这些场景,我想如果我遵循这些说明,我不会犯错误.如果我错了,请告诉我:)

我将尝试不使用自动释放,个人来说,通过使用自动释放,在某个自动释放池耗尽之前可能总会有一些冗余内存.我只会使用release,这可以确保我的应用程序随时使用最少的内存.

用我自己的话说,苹果说的另一件事是:每次我添加一个retain/alloc/copy,我都应该添加一个版本某处.

以下是我总结的所有场景:

  1. 在同一个函数中:分配一个对象,使用它并释放它

  2. 在类的init函数中,在类的dealloc函数中分配一个对象,释放该对象

  3. 当需要拥有一个指针时,应该在类的方法中保留一个输入指针(比如方法A),然后在类的dealloc函数中释放指针.

    我发现在目标c 中使用retain的时间与在c/c ++ 中使用memcpy的时间相同,所以我将retain作为"内存有效副本"

    如果输入保留指针要设置为成员指针变量,则应首先释放成员指针.因此,在情况下[3],ALLOC在初始化类的配对与释放在方法A,而保留在方法A配对与释放在的dealloc

  4. 返回指针作为返回值.老实说,当我使用c ++时,我从未做过这样的事情.如果要返回一个成员指针就可以了,因为有人会照顾它:

    -(UIButton*) getTheButton() {
        return theButton;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    但是返回指向本地分配对象的指针真的很糟糕:

    -(UIButton*) getTheButton() {
        UIButton* myButton = [[UIButton alloc] init];
        return myButton; //TERRIBLE!
    } 
    
    Run Code Online (Sandbox Code Playgroud)

    有人可能会说我应该在这种情况下使用自动释放,但我只是想通过使用它来绕过该解决方案:我只会返回成员指针,或者我不会返回指针,我只会对给定的输入指针进行操作.

    -void operateOnTheButton(UIButton* button) {
        [button release];
        button = [[UIButton alloc] init];
    } 
    
    Run Code Online (Sandbox Code Playgroud)

所以,如果我按照上面的内存使用说明,请告诉我是否有任何问题.

感谢:D

jas*_*own 9

您必须使用一个重要方案autorelease.如果您分配/保留/复制一个对象,然后将其返回给您拥有该对象的其他代码,但您不能release,因为其他代码需要使用它(或者你不会返回它).

在这种情况下,您必须通过向对象发送autorelease消息来对该对象的释放负责,从而确保它最终将被释放.这正是像NSString那样的基础方法stringWithString:.您没有release从此方法获得的字符串对象,因为您没有分配/保留/复制它,但如果该方法没有为您自动释放它,它将继续存在[pool drain]并成为内存泄漏.

确保您了解引用计数的工作原理.release减少对象的引用计数.当计数达到0时,对象被销毁.alloc并copy创建一个ref count为1 retain的对象.将接收对象的ref计数增加1.对于每个alloc/retain/copy,必须有一个release.1起,1下来.

因此,当您返回一个您创建的对象时,将控制传递给被调用者,您会使1到1的等式失衡,因为您无法使用release它.这就是原因autorelease.它不会减少接收者的ref计数器,所以它没有被破坏的危险,但是当池耗尽时,池中的每个对象都会收到一条release消息autorelease,恢复平衡(除非有意保留对象)它会在排水管中存活下来,在这种情况下,被调用者release以后需要它.

至于第4点,你的第二个例子很好,如果你autorelease在基础课中有很多这种技术的例子.NSString,NSArray,NSDictionary等每个数据类都有返回本地分配的对象指针的方法.他们通常有形式thisWiththat:,如stringWithstring:或dictionaryWithContentsOfFile:.后者将分配一个字典对象,用文件内容填充它,自动释放它,并返回一个指向你的指针.它被称为工厂功能.obj-c中的常见模式,java也是如此.

您是第三个代码示例,稍后会导致运行时错误.您正在发布一个您不拥有的对象.所有者不会指望release它,这可能意味着它将收到太多release消息,从而导致运行时错误.如果你没有分配/保留/复制它,你就不拥有它,所以你不应该发布它.

  • 第4点的示例,示例3也是关闭的:它不会在传入指针上创建mem泄漏.它释放它不拥有的传入对象(导致稍后过度释放,从而导致一些EXC_BAD_ACCESS),然后泄漏新实例. (2认同)