我有一个带代表的控制器。
@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
之后,我看到第一个地址,即给我麻烦的地址,在我到达之前被分配并释放了很多次。第二个对象只分配一次。在什么条件下指针可以像这样重复使用?
答案 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秒内修改了代码。