代码之家  ›  专栏  ›  技术社区  ›  Kurbz

iPhone基本内存管理

  •  1
  • Kurbz  · 技术社区  · 15 年前

    release 之后 alloc -viewDidLoad .

    SomeViewController.h

    #import <UIKit/UIKit.h>
    
    @interface SomeViewController : UIViewController {
        UIButton *someButton;
        NSString *someString;
    }
    
    @property (nonatomic, retain) IBOutlet UIButton *someButton;
    @property (nonatomic, copy) NSString *someString;
    
    @end
    

    SomeViewController.m

    #import "SomeViewController.h"
    
    @implementation SomeViewController
    
    @synthesize someButton, someString;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        someButton = [[UIButton alloc] init];
        someString = [[NSString alloc] init];
    }
    
    - (void)viewDidUnload {
        self.someButton = nil;
        self.someString = nil;
    }
    
    - (void)dealloc {
        [someButton release], self.someButton = nil; 
        [someString release], self.someString = nil;
        [super dealloc];
    }
    
    @end
    

    谢谢

    编辑: UIButton 在IB,我还需要吗 是吗?

    3 回复  |  直到 15 年前
        1
  •  2
  •   Austen Green    15 年前

    在对象上调用init时,retain计数变为1。您有两个不同的setter属性:一个是UIButton的“retain”,另一个是NSString的“copy”。当你打电话的时候

    self.someButton = someUIButtonObject;
    

    NSString的另一个例子有不同的问题,但仍然会泄漏内存。在这里,您对[[NSString alloc]init]的调用将产生一个新的string对象,然后调用

    self.someString = someNSStringObject;
    

    一个简短的旁注:我不知道您的实际代码是什么样子的,但是不要忘记NSStrings是不可变的(因此仅仅调用[[NSString alloc]init]是非常无用的),UIButton需要一个框架(尝试[[UIButton alloc]initWithFrame:(cRect)frame];)。

    self.someButton = [[[UIButton alloc] init] autorelease];
    

    它将释放物体,尽管在未来的某个未知时间。不要使用自动释放,如果你的内存非常紧张,你需要尽快记忆。在这种情况下,您可以:

    UIButton* tempButton = [[UIButton alloc] init];
    self.someButton = tempButton;
    [tempButton release];
    

    这保证了在自动释放池中不会有大型对象等待。

    另外,始终使用getter/setter访问这些属性(self.someButton而不是someButton)。这样就不会意外地将someButton分配给新指针并泄漏旧指针。

    在IB中创建按钮时,XIB保存对按钮的引用(+1 retain count)。如果您创建一个IBOutlet以便以编程方式访问按钮,那么对象上会有另一个retain,因此如果您有一个IBOutlet到someButton,那么加载XIB后someButton的retain计数为2。您不需要分配对象,这是在将XIB加载到内存时自动完成的。另外,您只负责释放对按钮的一个引用(IBOutlet引用)。一般来说,一旦你知道你不再需要它,就发布它是一个很好的实践。例如,如果您知道您需要一个按钮,并且必须进行初始自定义,而无需其他操作,那么您可能会执行以下操作:

    -(void)viewDidLoad {
      // Do some customization of someButton
      [someButton release];
    }
    

    否则,您可能会在viewDidUnload中释放某个按钮,因为您知道此时不再需要对该按钮的引用。

        2
  •  4
  •   mvds    15 年前

    这是一个很长的故事,你可以通过谷歌搜索发现,有人可能会进入这里,但为了保持简短,这里有一些调整:

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.someButton = [[[UIButton alloc] init] autorelease];
        self.someString = [[[NSString alloc] init] autorelease];
    }
    

    即使用设置器( self.something = ...; release autorelease 任何 alloc 你知道(逻辑上的区别是谁“拥有”这些物体;通过这些调整,函数放弃了所有权,类得到了所有权。)

    不,如果你在IB中创建了一个按钮,这个按钮就在那里,用你的样式分配和初始化。

        3
  •  0
  •   Niko    15 年前

    基本上,您使用 alloc new release 在你代码的某个地方。如果它是一个接口变量,您应该在 dealloc