当运行分析器时,我收到了"Object sent -autorelease too many“警告。我知道我在做一些棘手的事情(并且对实现我的目标的其他选择持开放态度)。
从本质上讲,我希望保留一堆特定类型的控制器,以便从中央位置发送消息。因此,考虑到:
从'ActionBroker‘共享对象:
NSMutableSet *liveActions;
liveActions = [NSMutableSet alloc] init];..。
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代码:
[[CLActionBroker sharedActionBroker] removeAction: self];
[super dealloc];..。在removeAction中:
[action retain];
[self.liveActions removeObject:action];上面的代码工作正常,我只是得到了纠缠不休的错误。还有一种纠结的感觉,那就是我也许可以用不同的方式解决这个问题。
此代码的用例之一是通过一系列打开的控制器传递一个'handleOpenURL‘请求,并返回第一个'YES’响应。
发布于 2011-08-06 14:47:46
据我所知,你的意图是在集合中有一组控制器(“动作”),你可以从应用程序的任何地方轻松地访问它们。如果这些控制器中的一个被释放,它将自动从集合中删除自己。
但是,这个设置有一个问题。如上所述,控制器应该在释放时从liveActions集合中删除。但是,由于NSSet保留其成员,所以只要控制器仍在liveActions集合中,它就永远不会被释放。只有在释放平衡了所有保留的情况下,才会运行-dealloc。
这,然后导致您的过度释放,从而导致警告。由于您已经发送了一个额外的版本,因此可以在控制器仍在liveActions集合中的情况下运行-dealloc。但是当您将其从该集合中删除时,它将向您的对象发送一条release消息,这将使其保留计数为负数。这可能是安全的,也可能是不安全的,但无论是哪种情况,它都是一个丑陋的变通办法。
看起来,你真正想要的是一个不保留成员的集合。这通常是一种危险的配置,因为它可能导致集合中的指针悬空。但是,如果您愿意管理对象的生命周期,并在适当的时候清除这些悬空指针,那么事实证明这是完全可行的。您只需要使用CFMutableSet而不是NSMutableSet。由于两者都是免费桥接的,所以它甚至不会增加太多的复杂性。
设置CFMutableSet如下所示:
// 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将会很特别,因为它不会保留其成员。
发布于 2011-08-06 13:07:59
问题是:
CLViewController *action = [[[actionClass alloc] init] autorelease]; // +0 ownership
// ...
[self.liveActions addObject: action]; // liveActions takes ownership
// ...
[action release]; // -1 ownership当你已经alloc了对象,你要对它负责。但是当你autorelease它的时候,你已经完成了你的义务(因为你是自动释放的,而不是释放,你仍然可以使用这个对象,直到运行循环的下一个循环)。你不应该稍后再release它。
另外:
[action retain];
[self.liveActions removeObject:action];保留是不必要的。
(这是另一个开始切换到ARC的插件,在这个插件下,您不必担心这个问题!)
编辑:误解了您的问题。修订后的答案即将公布。
https://stackoverflow.com/questions/6964873
复制相似问题