iOS – pipe理IBOutlets内存的最佳方法是什么?

我一直在审查苹果文档和示例代码,试图确定pipe理IBOutlets的内存的最佳方式。 我有点困惑,至less可以说。

CurrentAddress示例代码将IBOutlets声明为属性:

@interface MapViewController : UIViewController <MKMapViewDelegate, MKReverseGeocoderDelegate> { MKMapView *mapView; UIBarButtonItem *getAddressButton; } @property (nonatomic, retain) IBOutlet MKMapView *mapView; @property (nonatomic, retain) IBOutlet UIBarButtonItem *getAddressButton; 

大。 这些是在dealloc中发布的:

 - (void)dealloc { [mapView release]; [getAddressButton release]; [super dealloc]; } 

现在不应该将这些属性设置为分配吗? 因为当设置保留时,IBOutlet的保留计数将会增加两次:一次是装入笔尖时,另一次是设置属性? 将这些属性设置为零而不是释放dealloc不是更好吗?

苹果文档说,我们应该保留iOS的属性。
应该在deallocviewDidUnload释放和nil保留的sockets。

在Mac上,装入笔尖时,未被超级视图保留的每个sockets都会自动保留。 iOS的情况并非如此。 这就是为什么在视图层次结构中只保留视图之外的其他视图在理论上是有效的。

Jeff LaMarche提供了一个非常有用的post: Outlets,Cocoa和Cocoa Touch 。

一旦nib载入程序完成载入所有内容并连接所有IBOutlet,它就会自动释放载入的所有对象。 如果您的IBOutlet属性被声明为assign ,那么在下一次autorelease池清空时,它指向的对象将被删除。

您可以将这些属性设置为dealloc而不是直接释放它们,结果是一样的。 需要注意的是,如果您提供了自己的setter实现,则需要记住对象的某些其他成员可能已经被释放。

这对于MacOSX和iOS来说是不同的。 在iOS中,加载视图和build立笔尖连接后,保留计数将为2。

这些元素中的每一个都将被视图保留一次,并由您的控制器保留一次。 视图中的其他元素将仅保留在视图中。

当你的控制器释放这两个元素时,他们的保留数就下降到一个。 之后,[super dealloc]被调用。 UIViewController在其dealloc中有一个[view release],所以视图被释放(除非保留在其他地方,或者以前被释放)。 当视图被释放时,它释放它的子视图,并且元素最终被完全释放。

dealloc中优先使用[object release]的原因是,当您编写[self setObject:nil]时,键值编码(或您自己的代码)可能会导致运行额外的代码。 这可能会导致其他对象在控制器处于释放状态时与控制器进行交互。 出于同样的原因,不应该在init方法中使用Setter。

还有第二个原因是刚刚发布。 通过保留值而不是将其设置为零,我们会注意到代码在dealloc期间是否错误地访问了该对象上的variables。 这可以帮助捕捉可能不容易追踪的错误。

我假设你@synthesize这些属性。 如果你没有,你需要手动释放自己。 你的假设是非常正确的,如果你在财产设置的时候继续保留,你会泄漏记忆。

让我们来思考….在我们拥有花哨的@synthesize语句之前,属性曾经看起来像什么?

 id _propertyName; // the ivar - (id) propertyName { return _propertyName; } - (void) setPropertyName:(id)v { if (_propertyName) { [_propertyName release]; // release the previously retained property } _propertyName = [v retain]; // retain this one so it doesn't fly away on us } 

现在,你不需要input这些东西,因为@synthesize很酷并且为你生成,如果你没有指定nonatomic话,它也会生成@synchronized块,这也是非常好的。

如果你指定了assign而不是retain ,你会得到这样的东西

 id _propertyName; // the ivar - (id) propertyName { return _propertyName; } - (void) setPropertyName:(id)v { _propertyName = v; } 

当事物不是对象时,这是唯一可以做的事情,因为它们只是值(有时也被称为值types,对象是引用types)。 由于价值types不能保留,其他types的块没有任何意义。 继续尝试使用BOOL创build一个retain属性,并观察LLVM或GCC告诉你去做什么;)

不应该将这些属性设置为分配吗? 因为当设置为保留时,IBOutlet的保留计数将增加两次:一次是装入笔尖时,另一次是设置属性

好吧,你发布的代码是正确的。

当你使用:

 @property (nonatomic, retain) IBOutlet MKMapView *mapView; 

你只是告诉xCode创build一个setter方法,它将创build你的MKMapView对象,并在你每次调用时保留它

 yourMapViewController.mapView = someMapView; // from out // or self.mapView = someMapView; // from in 

之后,mapView保留计数增加+1和你的MapViewController代码需要“现在你可以指向mapView和pipe理它…

不要担心IB笔尖文件…

当你加载一个UIBiewController与一个笔尖,在你的情况下,类MapViewController:UIViewController,当你释放你的MapViewController时,IB笔尖对象将释放…只是照顾你保留的对象…