Obj-C,在线分配的对象的潜在泄漏,UIBarButtonItem alloc

时间:2011-11-10 22:09:14

标签: objective-c xcode cocoa-touch analyzer

我得到了一个分析器泄漏,但这是我在别处没有问题的相同代码。我知道我正在使用alloc,因此我必须释放,但我在dealloc中这样做。

我做错了什么?

标题文件:

@interface myViewController : UIViewController <UITableViewDataSource, 
               UITableViewDelegate> {

    UIBarButtonItem *addButton;
}
@property (nonatomic, retain) UIBarButtonItem *addButton;

主档案:

@synthesize addButton;
- (void)viewDidLoad {

    NSMutableArray* buttons = [[NSMutableArray alloc] initWithCapacity:3];


    addButton = [[UIBarButtonItem alloc]
                            initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                            target:self action:@selector(btnNavAddPressed:)];
    addButton.style = UIBarButtonItemStyleBordered;
    [buttons addObject:addButton];

    [tools setItems:buttons animated:NO];
    [buttons release];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] 
                                initWithCustomView:tools];

    addButton.enabled = FALSE;

- (void)dealloc {
    [addButton release];

4 个答案:

答案 0 :(得分:2)

您没有使用setter,代码应为:

self.addButton = [[[UIBarButtonItem alloc]
                        initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                        target:self action:@selector(btnNavAddPressed:)] autorelease];

使用名称与属性名称不同的ivar可以避免此类问题。这是在@synthesize声明中完成的:

@synthesize addButton = _addButton;

这样,任何遗漏self都会导致错误消息。

这是一个完整的实现(除了tools未定义),属性addButton是所有地方的句柄:

@interface myViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
}
@property (nonatomic, retain) UIBarButtonItem *addButton;
@end

@implementation myViewController
@synthesize addButton = _addButton;

- (void)viewDidLoad {
    NSMutableArray* buttons = [NSMutableArray array];

    self.addButton = [[UIBarButtonItem alloc]
                 initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                 target:self action:@selector(btnNavAddPressed:)];
    self.addButton.style = UIBarButtonItemStyleBordered;
    [buttons addObject:self.addButton];

    [tools setItems:buttons animated:NO];

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:tools] autorelease];

    self.addButton.enabled = FALSE;
}
- (void)dealloc {
    [_addButton release];
}
@end

答案 1 :(得分:2)

当您使用属性并为其分配时,您指定的属性将确定在分配给属性时是否增加retainCount。在您的情况下,您指定了&#34; retain&#34;这意味着处理属性赋值的setter函数将自动增加对象的保留计数。

然而,当你写

 addButton = [[UIBarButtonItem alloc]
                            initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                            target:self action:@selector(btnNavAddPressed:)];

你正在创建一个已经保留count == 1的opject,所以当你指定它时会有保留计数2.正确的方法是创建一个临时变量并创建对象,然后将temp变量赋给之后释放临时财产。变量:

UIBarButtonItem* tmp = [[UIBarButtonItem alloc]
                            initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                            target:self action:@selector(btnNavAddPressed:)];
self.addButton = tmp;
[tmp release];

当然我建议使用比“临时”更具描述性的名称。作为变量名。

答案 2 :(得分:1)

上述答案都具有误导性。您不需要使用setter,将对象直接分配给iVars是完全没问题的。但是,您确实需要释放您分配或保留的任何内容。你遇到的问题是:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:tools];

此行正在分配UIBarButtonItem个实例,并将其设置为rightBarButtonItem的{​​{1}}属性。这意味着navigationItem保留navigationItem并且它负责保留。你负责释放UIBarButtonItem的b / c而你不是。将代码更改为:

alloc

这种泄漏消失了。

答案 3 :(得分:0)

您没有利用声明的属性,但我认为addButton没有任何问题。泄漏似乎更多:

self.navigationItem.rightBarButtonItem = 
                             [[UIBarButtonItem alloc] initWithCustomView:tools];

只需添加autorelease,泄漏就会消失。