在什么条件下,地址上的对象可以改变? (OBJ-c)的

时间:2009-10-01 16:06:04

标签: objective-c memory

我有一个带代表的控制器。

@interface MyConversionController : NSObject {
    id <ConversionDelegate> _delegate;
}
@property (assign) id delegate;
@end    

@implementation
@synthesize delegate = _delegate;
@end

我收到Unrecognized selector sent to instance 0x36c4a0错误。我在-(void)setDelegate(id)delegate方法上设置了一个断点,这样我就可以观察传递到MyConversionController类的对象。我的setDelegate方法被调用两次,第一次是地址0x36c4a0的对象,我知道该对象符合<ConversionDelegate>协议。第二次调用此方法时,传入另一个符合协议的对象。当开始在委托上调用方法时,方法调用将被发送到第一个对象(0x36c4a0),该对象现在是另一种对象(通常是CFString__NSFastEnumerationEnumerator这有所不同。)

有谁知道为什么会发生这种情况?


在运行malloc_history之后,我看到第一个地址,即给我麻烦的地址,在我到达之前被分配并释放了很多次。第二个对象只分配一次。在什么条件下指针可以像这样重复使用?

2 个答案:

答案 0 :(得分:1)

您可能希望使用malloc_history在该地址中查找对象的callstack。在进程运行时在终端中执行以下操作:

malloc_history <pid> 0x36c4a0 # insert the address in question for the 2nd arg

您还需要启用MallocStackLogging(感谢Kubi对此的评论)。

这可以帮助您了解分配该地址的对象的位置。


此外,您已将委托标记为已分配,但未保留,但我认为这适用于代理人。也就是说,如果它在其他地方被自动释放,那么该内存可能会被重用。

你是否可以自动释放代表并分配它?类似的东西:

delegate = [[[ConversionDelegateClass alloc] init] autorelease];
controller.delegate = delegate

如果是这样,代理将在下一个autopool发行版中发布,因为没有任何东西保留它,并且该内存位置可以重复使用。

答案 1 :(得分:0)

问题是代表被过早释放了。这很难调试的原因是我很久以前写过的代码中发生了重新分配,程序会在问题发生之前退出。编写新的代码段使程序保持打开状态的时间足够长,以便其他类开始向解除分配的对象发送消息。

解决方案:我使用Instruments中的Zombie模块运行代码。希望我几天前做过这个,我在查看Instruments的输出后30秒内修改了代码。