提问人:rustyshelf 提问时间:9/15/2008 最后编辑:Bill the Lizardrustyshelf 更新时间:4/13/2012 访问量:9396
我需要释放 xib 资源吗?
Do I need to release xib resources?
问:
如果我有类似 UILabel 链接到 xib 文件的东西,我是否需要在我的视图的 dealloc 上发布它?我问的原因是因为我没有分配它,这让我觉得我也不需要发布它? 例如(在标题中):
IBOutlet UILabel *lblExample;
在实现中:
....
[lblExample setText:@"whatever"];
....
-(void)dealloc{
[lblExample release];//?????????
}
答:
相关新闻: 了解 Cocoa 的参考计数 / Objective C
评论
从某种意义上说,您可以通过在 IB 中创建标签来分配标签。
IB所做的是查看您的IBOutlets以及它们是如何定义的。如果您有一个类变量,IB 将为其分配对某个对象的引用,则 IB 将为您向该对象发送 retain 消息。
如果您使用属性,IB将使用您必须设置值的属性,而不是显式保留该值。因此,您通常会将 IBOutlet 属性标记为 retain:
@property (nonatomic, retain) UILabel *lblExample;
因此,在以太的情况下(无论是否使用属性),您应该在 dealloc 中调用 release。
评论
我在 Apple 文档中找到了我想要的东西。简而言之,您可以将对象设置为释放和保留的属性(或者只是@property,@synthesize),但对于诸如 UILabels 之类的内容,您不必这样做:
任何作为 Nib 主视图的子视图的 IBOutlet 都不需要释放,因为它们将在创建对象时发送自动释放消息。您需要在 dealloc 中释放的唯一 IBOutlet 是顶级对象,如控制器或其他 NSObject。这在上面链接的 Apple 文档中都提到了。
评论
如果遵循现在被认为是最佳实践的做法,则应释放 outlet 属性,因为应该在 set 访问器中保留它们:
@interface MyController : MySuperclass {
Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end
@implementation MyController
@synthesize uiElement;
- (void)dealloc {
[uiElement release];
[super dealloc];
}
@end
这种方法的优点是,它使内存管理语义明确明了,并且它在所有平台上一致地适用于所有 nib 文件。
注意:以下注释仅适用于 3.0 之前的 iOS。在 3.0 及更高版本中,您应该简单地将 viewDidUnload 中的属性值清空。
不过,这里的一个注意事项是,当控制器可能会释放其用户界面并按需动态重新加载它时(例如,如果您有一个视图控制器,它从 nib 文件加载视图,但根据请求(例如在内存压力下)释放它,并期望在再次需要视图时可以重新加载它)。在这种情况下,您需要确保在释放主视图时也放弃任何其他出口的所有权,以便也可以解除分配这些出口。对于 UIViewController,可以通过重写来处理此问题,如下所示:setView:
- (void)setView:(UIView *)newView {
if (newView == nil) {
self.uiElement = nil;
}
[super setView:aView];
}
不幸的是,这引发了另一个问题。由于 UIViewController 当前使用访问器方法实现其方法(而不是简单地直接释放变量),因此将被调用并响应内存警告...这将导致 中的崩溃。dealloc
setView:
self.anOutlet = nil
dealloc
dealloc
补救措施是确保出口变量也设置为:nil
dealloc
- (void)dealloc {
// release outlets and set variables to nil
[anOutlet release], anOutlet = nil;
[super dealloc];
}
评论
self.uiElement = nil;
viewDidUnload
setView:
self.anOutlet = nil;
这
[anOutlet release], anOutlet = nil;
如果你正确地编写了 setView:,那么部分是完全多余的。
评论
如果您不在 dealloc 上发布它,它会增加内存占用。
如果未将 IBOutlet 设置为属性,而只是将其设置为实例变量,则仍必须释放它。这是因为在 initWithNib 上,内存将分配给所有 IBOutlet。因此,这是您必须释放的特殊情况之一,即使您没有在代码中保留或分配任何内存。
评论