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

发布于 2024-12-15 00:17:49 字数 1068 浏览 3 评论 0原文

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

I'm getting an analyser leak, however this is the same code i'm using elsewhere without a problem. I know I'm using alloc and therefore I have to release, but I am doing this in dealloc.

What am I doing wrong ?

Header file:

@interface myViewController : UIViewController <UITableViewDataSource, 
               UITableViewDelegate> {

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

Main file:

@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];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情话已封尘 2024-12-22 00:17:50

当您使用属性并向其分配指定的属性时,将确定在分配给该属性时保留计数是否递增。在您的情况下,您指定了“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”更具描述性的名称作为变量名称。

when you use a property and assign to it the attributes you specified determine whether retainCount is incremented if you assign to the property. In your case you specified "retain" which means that the setter function that handles assignment to your property will automatically increment the retain count for the object.

However when you write

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

you are creating an opject with already retain count == 1 so when you assign it will have retain count 2. the proper way to do this is to create a temp variable and create the object, then assign the temp variable to the property thereafter releasing the temp. variable:

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

of course i would recommend a more descriptive name than 'temp' as variable name.

紫轩蝶泪 2024-12-22 00:17:50

您没有使用 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

You are not using the setter, the code should be:

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

This type of problem can be avoided by using an ivar that has a different name than the property name. This is accomplished in the @synthesize statement:

@synthesize addButton = _addButton;

This way any omission of self will result in an error message.

Here is a full implementation (except tools is undefined), the property addButton is handles in all places:

@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
一袭水袖舞倾城 2024-12-22 00:17:50

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

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

这一行分配一个 UIBarButtonItem 实例并将其设置为 navigationItemrightBarButtonItem 属性。这意味着 navigationItem 正在保留 UIBarButtonItem 并且它负责该保留。您有责任在 alloc 中释放它,但您没有。将代码更改为:

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

这样泄漏就消失了。

Both the above answers are misleading. You don't need to use a setter, it's perfectly fine to assign objects directly to iVars. You do need to release anything you alloc or retain however. The problem you have is here:

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

This line is alloc'ing a UIBarButtonItem instance and setting it to the rightBarButtonItem property of the navigationItem. That means the navigationItem is retaining the UIBarButtonItem and it is responsible for that retain. You are responsible for releasing it b/c of the alloc and you are not. Change the code to this:

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

and this leak goes away.

吻风 2024-12-22 00:17:50

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

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

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

You are not taking advantage of the declared property but I don't see any problem with addButton. The leak seems more in:

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

Just add autorelease and the leak will go away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文