2

我遇到了分析器泄漏,但是这是我在其他地方使用的相同代码,没有问题。我知道我正在使用 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

4 回答 4

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
于 2011-11-10T22:13:22.163 回答
2

当您使用属性并将其分配给它时,您指定的属性确定如果您分配给该属性,retainCount 是否会增加。在您的情况下,您指定了“ retain”,这意味着处理分配给您的属性的 setter 函数将自动增加对象的保留计数。

但是当你写

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

您正在创建一个已经保留计数 == 1 的对象,因此当您分配它时,它将保留计数 2。执行此操作的正确方法是创建一个临时变量并创建对象,然后将临时变量分配给属性,然后释放温度。多变的:

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

当然,我会推荐一个比“temp”更具描述性的名称作为变量名。

于 2011-11-10T22:16:29.183 回答
1

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

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

这一行正在分配一个UIBarButtonItem实例并将其设置rightBarButtonItemnavigationItem. 这意味着它navigationItem正在保留UIBarButtonItem并且它负责保留。您有责任以 b/c 的形式发布它,alloc而您没有责任。将代码更改为:

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

这种泄漏消失了。

于 2011-11-10T22:24:35.540 回答
0

您没有利用声明的属性,但我认为addButton. 泄漏似乎更多:

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

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

于 2011-11-10T22:24:51.307 回答