iPhone内存管理和发布

Joh*_*how 6 iphone cocoa memory-management objective-c nsview

这是我经常看到的一种常见做法(包括来自非常受欢迎的iPhone开发者书籍)

在.h文件中:

@interface SomeViewController : UIViewController
{
  UIImageView *imgView;
}
Run Code Online (Sandbox Code Playgroud)

在.m文件中的某个地方:

imgView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen]
applicationFrame]];
[imgView setImage:[UIImage imageNamed:@"someimage.png"]];
[self addSubview:imgView];
[imgView release];
Run Code Online (Sandbox Code Playgroud)

后来,我们看到了......

- (void) dealloc
{
  [imgView release];
  [super dealloc];

} 
Run Code Online (Sandbox Code Playgroud)

由于imgView具有匹配的alloc和release,是否需要在dealloc中发布imgView?

addSubview调用保留的imgView在哪里占了?

Dan*_*son 9

代码不正确.在你imgView被解除分配后,你最终会被释放.

在.m文件中,您:

  1. alloc 它 - >你拥有它
  2. 将其添加为子视图 - >您和UIView拥有它
  3. release 它 - >你不拥有它

然后dealloc,release即使你在我们在上面的步骤3中建立了你不拥有它,你也可以使用imgView.当你打电话时[super dealloc],视图将释放它的所有子视图,我想你会得到一个例外.

如果你想保留一个ivar imgView,我建议你在将它添加为子视图后不要打电话release,并保持dealloc相同.这样,即使imgView在某个时候从视图层次结构中删除,您仍然会有一个有效的引用.


Tob*_*hen -1

是的,该代码有问题。它过早释放 imgView ,在极少数情况下可能会导致崩溃,将对象存储在实例变量中而不保留它,而且它通常以错误的方式进行内存管理。

一种正确的方法是:

@interface SomeViewController : UIViewController
{
    UIImageView *imgView;
}
@property (nonatomic, retain) UIImageView *imgView;
Run Code Online (Sandbox Code Playgroud)

并在实施中;

@synthesize imgView;
Run Code Online (Sandbox Code Playgroud)

模块中的某处:

//Create a new image view object and store it in a local variable (retain count 1)
UIImageView *newImgView = [[UIImageView alloc] initWithFrame:self.view.bounds];
newImgView.image = [UIImage imageNamed:@"someimage.png"];

//Use our property to store our new image view as an instance variable,
//if an old value of imgView exists, it will be released by generated method,
//and our newImgView gets retained (retain count 2)
self.imgView = newImgView;

//Release local variable, since the new UIImageView is safely stored in the
//imgView instance variable. (retain count 1)
[newImgView release];

//Add the new imgView to main view, it's retain count will be incremented,
//and the UIImageView will remain in memory until it is released by both the
//main view and this controller. (retain count 2)
[self.view addSubview:self.imgView];
Run Code Online (Sandbox Code Playgroud)

并且 dealloc 保持不变:

- (void) dealloc
{
    [imgView release];
    [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

  • imgView 发布的还不算太早。它被 addSubview 保留。这是一种非常常见的习惯用法,在通过 addSubview 添加后立即释放(或任何其他保留的调用,例如 UINavigationController 的 PushViewController)。 (3认同)