首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略‘对象发送-autorelease的次数太多’警告

忽略‘对象发送-autorelease的次数太多’警告
EN

Stack Overflow用户
提问于 2011-08-06 12:53:51
回答 2查看 1K关注 0票数 1

当运行分析器时,我收到了"Object sent -autorelease too many“警告。我知道我在做一些棘手的事情(并且对实现我的目标的其他选择持开放态度)。

从本质上讲,我希望保留一堆特定类型的控制器,以便从中央位置发送消息。因此,考虑到:

从'ActionBroker‘共享对象:

代码语言:javascript
复制
NSMutableSet *liveActions;
liveActions = [NSMutableSet alloc] init];

..。

代码语言:javascript
复制
CLViewController *action = [[[actionClass alloc] init] autorelease];
if (!action) {
    return nil;
}    
[self.liveActions addObject: action];
// When adding an object, the retain count is increased. We want the action
// to dealloc, so that it might remove itself from the list...
[action release];
return action;    

和互补的dealloc代码:

代码语言:javascript
复制
[[CLActionBroker sharedActionBroker] removeAction: self];        
[super dealloc];

..。在removeAction中:

代码语言:javascript
复制
[action retain];
[self.liveActions removeObject:action];

上面的代码工作正常,我只是得到了纠缠不休的错误。还有一种纠结的感觉,那就是我也许可以用不同的方式解决这个问题。

此代码的用例之一是通过一系列打开的控制器传递一个'handleOpenURL‘请求,并返回第一个'YES’响应。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-08-06 14:47:46

据我所知,你的意图是在集合中有一组控制器(“动作”),你可以从应用程序的任何地方轻松地访问它们。如果这些控制器中的一个被释放,它将自动从集合中删除自己。

但是,这个设置有一个问题。如上所述,控制器应该在释放时从liveActions集合中删除。但是,由于NSSet保留其成员,所以只要控制器仍在liveActions集合中,它就永远不会被释放。只有在释放平衡了所有保留的情况下,才会运行-dealloc

这,然后导致您的过度释放,从而导致警告。由于您已经发送了一个额外的版本,因此可以在控制器仍在liveActions集合中的情况下运行-dealloc。但是当您将其从该集合中删除时,它将向您的对象发送一条release消息,这将使其保留计数为负数。这可能是安全的,也可能是不安全的,但无论是哪种情况,它都是一个丑陋的变通办法。

看起来,你真正想要的是一个不保留成员的集合。这通常是一种危险的配置,因为它可能导致集合中的指针悬空。但是,如果您愿意管理对象的生命周期,并在适当的时候清除这些悬空指针,那么事实证明这是完全可行的。您只需要使用CFMutableSet而不是NSMutableSet。由于两者都是免费桥接的,所以它甚至不会增加太多的复杂性。

设置CFMutableSet如下所示:

代码语言:javascript
复制
// The NULL for the third parameter tells the set to not do anything when
// an object is added to or removed from the set.
CFMutableSetRef cfLiveActions = CFSetCreateMutable(NULL, 0, NULL);

// Toll-free bridging makes this possible
NSMutableSet *liveActions = (NSMutableSet *)cfLiveActions;

在那之后,您就可以像使用任何其他NSMutableSet一样使用它了;这个any将会很特别,因为它不会保留其成员。

票数 3
EN

Stack Overflow用户

发布于 2011-08-06 13:07:59

问题是:

代码语言:javascript
复制
CLViewController *action = [[[actionClass alloc] init] autorelease]; // +0 ownership
// ...
[self.liveActions addObject: action]; // liveActions takes ownership
// ...
[action release]; // -1 ownership

当你已经alloc了对象,你要对它负责。但是当你autorelease它的时候,你已经完成了你的义务(因为你是自动释放的,而不是释放,你仍然可以使用这个对象,直到运行循环的下一个循环)。你不应该稍后再release它。

另外:

代码语言:javascript
复制
[action retain];
[self.liveActions removeObject:action];

保留是不必要的。

(这是另一个开始切换到ARC的插件,在这个插件下,您不必担心这个问题!)

编辑:误解了您的问题。修订后的答案即将公布。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6964873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档