我是Objective-c和xcode的新手,我目前正在编写的应用程序收到了臭名昭著的EXC_BAD_ACCESS
错误。
几乎每个人都建议开始使用NSZombies来解决问题。我想我有 NSZombies 工作,但是当我的应用程序崩溃时, xcode没有给我一个关于僵尸消息的警报。
在继续调试之前,我想运行一些代码,这些代码肯定会导致将消息发送到僵尸(解除分配的对象)。
什么是一个简单的代码片段,其中一条消息被发送到一个已释放的对象,导致NSZombies应该提醒我的场景?
我是Objective-c和xcode的新手,我目前正在编写的应用程序收到了臭名昭著的EXC_BAD_ACCESS
错误。
几乎每个人都建议开始使用NSZombies来解决问题。我想我有 NSZombies 工作,但是当我的应用程序崩溃时, xcode没有给我一个关于僵尸消息的警报。
在继续调试之前,我想运行一些代码,这些代码肯定会导致将消息发送到僵尸(解除分配的对象)。
什么是一个简单的代码片段,其中一条消息被发送到一个已释放的对象,导致NSZombies应该提醒我的场景?
对于非 ARC 代码:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
[a release];
NSLog(@"%@", [a description]);
}
这将为您提供 EXC_BAD_ACCESS 关闭 Zombies,并在启用 Zombies 的情况下提供“发送到已释放实例的消息”消息。
如果您的项目使用 ARC,那么将消息可靠地传递给已释放的对象会有点困难(毕竟这就是 ARC的重点)。
这有效:
- (IBAction) messageZombie:(id)sender {
id a = [[NSObject alloc]init];
id __unsafe_unretained b =a;
a=nil;
NSLog(@"%@", [b description]);
}
它可能与您的实际代码所做的不太相似,因为到底是谁使用 __unsafe_unretained 呢?但是如果你只是想确保你已经正确打开了 NSZombies,这应该是一个合理的测试用例。
如果您在代码中寻找可疑的地方,那么一定要寻找 __unsafe_unretained 指针,尽管您不会找到任何*,并仔细检查正确的转换是否用于转换为 Cocoa 对象的 CoreFoundation 对象。
* 如果你的项目需要支持 10.7 之前的 OS X 版本,或者 5.0 之前的 iOS 版本,那么你不能使用 __weak 指针,所以在那种项目中,你会发现 __unsafe_unretained 的使用频率更高。
您可以创建一个 CF 对象,将其桥接到一个 Objective-C 对象,然后释放它并尝试使用桥接对象。我认为您必须使用__bridge
它才能按照您想要的方式行事。