其他人在XCode 4.2(Lion)或4.0.2中遇到4.3 iPhone模拟器的问题?
我的代码长期以来一直在工作,测试和生产中使用块来指定完成操作。例如,我使用UIView动画来淡出标签顶部的一些文本,如下所示:
[UIView animateWithDuration: 0.0
delay: 0.0
options: (UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone)
animations: ^{
videoTextLabel1.alpha = 0.0;
videoTextLabel2.alpha = 0.0;
videoTextLabel3.alpha = 0.0;
}
completion: ^(BOOL completed) {
[self fadeInNextMeditationLine: 0];
}];
我可以在模拟器中可靠地获得EXEC_BAD_ACCESS - 从不会在设备上出现问题。
在另一个地方,我使用自己的完成块实现在用户取消模态视图后采取行动。
ValuePickerController *controller =
[[ValuePickerController alloc]
initWithNibName: kValuePickerXIBFileName
bundle: nil
labelText: @"prompt")
value: alertSettings.frequency
minimumValue: kMinimumFrequency
maximumValue: kMaximumFrequency
completionBlock: ^(NSInteger newValue) {
[self updateFrequencyText: newValue];
[self changeFrequencySetting];
}];
没有NSZombies出现,分析仪运行干净。此外,此代码已生产6个月,没有崩溃。
其他人有这个麻烦吗?自从我升级XCode以来,它一直在发生。
答案 0 :(得分:22)
据我所知,这是一个已知问题,只影响4.3模拟器。 4.2和预发行版5.0版本似乎没有出现此问题。然而,Lion现在出了问题,因为Xcode的最新通用版本只支持4.3模拟器,而这个问题就出现了。
实际原因是Block和ObjC运行时之间的钩子。块本身也可以正常工作,但任何在它们上调用Objective-C消息的尝试都会导致段错误。这是因为Blocks运行时包含对相关ObjC类的几个未初始化的引用,并且在iOS 4.3模拟器上,当ObjC运行时加载时它们从未被初始化(它们仅在ObjC被使用时才被初始化 - 所以Blocks运行时不依赖于加载Foundation。您可以在运行时通过查看调试器中_NSConcreteStackBlock
,_NSConcreteGlobalBlock
和_NSConcreteMallocBlock
的值来检查此问题。在4.2模拟器或设备上,这些值将是非零的,但在4.3模拟器上它们仍为零。
我有一个潜在的解决方案,如果有必要,我会链接到这里,但首先我要尝试&从苹果公司那里获取一些信息,告诉他们是否已经解决了发布的问题,或者他们是否需要更多信息等等。
更新:问题已解决
我做了很多挖掘,最终归结为:不使用-weak_library
对libSystem.dylib进行弱连接。相反,你应该根本不弱连接libSystem(我不得不支持iOS 3.1.x,因为在某些特定于iOS4的条件代码中编译器生成的Blocks代码在启动时导致链接错误,即坏的崩溃),或者你应该使用-weak lSystem
代替,模拟器可以更好地理解。
当您在iOS模拟器中运行时,您可以查看加载的库(在Xcode:'Product-> Debug-> Shared Libraries ...'),如果您搜索'Blocks',您会看到两个项目:libsystem_blocks.dylib
和libsystem_sim_blocks.dylib
。后者是由CoreFoundation链接的,它为Blocks运行时初始化ObjC运行时粘合剂。但是,由于您将libSystem
库作为一个整体进行弱链接,因此通常由Simulator版本覆盖的符号(因为它比libSystem更晚加载)实际上是在运行时从第一个< / em>实现它们的库。这意味着您将找到_NSConcreteGlobalBlock
和朋友的系统版本,这些版本不是由Simulator的自定义ObjC运行时初始化的版本。
对于(很多!)有关问题的更多信息,以及查看我如何跟踪它,请查看我创建的主题on the Apple Developer Forums。