在iPhone模拟器4.3 / XCode 4.2和4.0.2中使用块崩溃的应用程序

任何人在XCode 4.2(狮子)或4.0.2 4.3 iPhone模拟器有麻烦吗?

我有很长时间的工作,testing,并在生产中使用块来指定完成操作的代码。 例如,我使用UIViewanimation来淡出标签顶部的一些文本,如下所示:

[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以来一直在发生。

据我所知,这是一个已知的问题,只影响4.3模拟器。 4.2和prerelease 5.0版本似乎没有performance出这个问题。 不过现在Lion已经不在了,因为Xcode的最新版本只支持发生这个问题的4.3模拟器。

实际的原因是块和ObjC运行时之间的钩子。 块自己可以正常工作,但是任何尝试在它们上调用Objective-C消息都会导致段错误。 这是因为Blocks运行时包含了一些未初始化的对相关ObjC类的引用,在iOS 4.3模拟器上这些从未被初始化,当ObjC运行时加载时(只有在使用ObjC的时候才初始化 – 所以Blocks运行时不依赖于加载Foundation)。 您可以在运行时通过在debugging器中查看_NSConcreteStackBlock_NSConcreteGlobalBlock_NSConcreteMallocBlock的值来检查这一点。 在4.2模拟器或设备上,这些值将不为零,但在4.3模拟器上它们仍然为零。

我有一个潜在的解决scheme,如果有必要的话我会链接到这里,但是首先我要尝试从苹果公司那里获取一些信息,以确定他们是否有发行版本或者是否需要更多的信息等等。 。

更新:问题解决

我做了大量的挖掘工作,最终归结为: 不要使用-weak_library弱链接libSystem.dylib 。 相反,你不应该弱连接libSystem(我不得不支持iOS 3.1.x,因为编译器生成的块代码在一些特定于iOS4的条件代码在启动时导致链接错误,即坏的坏的崩溃),或者你应该使用-weak lSystem而不是模拟器更好地理解。

在iOS模拟器中运行时,可以查看已加载的库(在Xcode中:'Product-> Debug-> Shared Libraries …'),如果search'Blocks',则会看到两个项: libsystem_blocks.dyliblibsystem_sim_blocks.dylib 。 后者是由CoreFoundation链接的,它为Blocks运行时初始化ObjC运行时粘连。 然而,由于你将libSystem库作为一个整体连接起来很薄弱,所以通常被Simulator版本覆盖的符号(因为它的加载时间比libSystem晚)实际上是在运行时从实现它们的第一个库中覆盖的。 这意味着你可以find_NSConcreteGlobalBlock和好友的系统版本,这些不是由模拟器自定义的ObjC运行时初始化的。

有关这个问题的更多信息,请查看我在Apple开发者论坛上的post 。