Iphone 未使用的出口泄漏

Iphone 未使用的出口泄漏,iphone,objective-c,interface-builder,Iphone,Objective C,Interface Builder,因此,我通过XIB文件加载,它包含一组uibarbuttonims。调用viewDidLoad:时会使用一些项 @interface MyViewController : UIViewController { IBOutlet UIBarButtonItem *addButton; IBOutlet UIBarButtonItem *editButton; IBOutlet UIBarButtonItem *doneButton; } // NB: There are no p

因此,我通过XIB文件加载,它包含一组
uibarbuttonims
。调用
viewDidLoad:
时会使用一些项

@interface MyViewController : UIViewController  {

  IBOutlet UIBarButtonItem *addButton;
  IBOutlet UIBarButtonItem *editButton;
  IBOutlet UIBarButtonItem *doneButton;
}

// NB: There are no properties retaining anything.

@end

@implementation MyViewController

- (void)viewDidLoad {

  [super viewDidLoad];

  NSArray *initialToolbarItems = 
    [[NSArray alloc] initWithObjects: addButton, editButton, nil];

  self.toolbarItems = initialToolbarItems;
  [initialToolbarItems release];
}

- (void)dealloc {
  [super dealloc];

  // Nothing else to do here since we are not retaining anything.
  // … or are we? <insert dramatic music here>
}

@end
没有发生泄漏。如果在
viewDidLoad:

  NSArray *initialToolbarItems = 
    [[NSArray alloc] initWithObjects: addButton, editButton, doneButton, nil];

我的问题是:为什么我的
IBOutlet
在我不使用时会泄漏。我在任何时候都不会保留它。NIB加载程序应该拥有该对象,对吗?

如果您为iBooutlet声明了@property with(retain),它们将被保留并且必须被释放

数组将保留它们

我能想到的唯一一件事是:

nib加载程序将IBOutlet视为强引用。默认情况下保留所有插座,除非您特别指定。所以您仍然需要在dealoc和viewDidUnload中释放它们

您还可以使用指定的特性使其成为弱参照:

@property (nonatomic, assign) IBOutlet UIBarButtonItem *doneButton;

一些阅读:

btw:[super dealoc];你是@willcodejavaforfood,但不会改变泄漏。我没有保留它的属性。代码如您所见。好的,我不是100%确定。工具栏项有什么属性?我想你已经记住了。只需在DealLocal中添加[toolbarItems release],确实如此,但toolbarItems数组是UIViewController的一个属性。它由对[super dealoc]的调用负责,他会释放他创建的数组。是的,但当
[super dealoc]
释放
工具栏项
属性时,会为每个数组子项调用
释放:
。无论如何,这并不能解释为什么只有当
IBOutlet
未使用时才会出现问题。添加带有
assign
的属性可以消除泄漏。谢谢另一方面,这并不能解释为什么在我实际使用插座时,插座被正确释放,例如,就像上面的最后一段代码一样。这意味着UINibLoading仅在其“保留的插座”被其他设备保留时才释放它们!多么复杂啊!我还没来得及阅读你链接的整篇文章,但你似乎一针见血!当我不想写属性的时候,苹果强迫我写属性是多么残忍啊。(针对具有相同问题的任何人的更新。有两种解决方案。1.始终使用
retain
为每个插座创建属性。并在
-viewDidUnload:
中将其设置为
nil
,然后在
-dealloc:
中释放ivar。如果将属性设置为
assign
,则必须确保在您想使用时加载插座!#2或者像我一样,不要为插座创建属性,除非您确实需要它们。然后在
-viewDidUnload:
do
[myOutlet release],myOutlet=nil;
-dealoc:
do
[myOutlet release]
中,最终代码会更少。
@property (nonatomic, assign) IBOutlet UIBarButtonItem *doneButton;