Objective c 在iPhone模拟器4.3/XCode 4.2和4.0.2中使用Blocks崩溃应用程序

Objective c 在iPhone模拟器4.3/XCode 4.2和4.0.2中使用Blocks崩溃应用程序,objective-c,ios,xcode,ios-simulator,objective-c-blocks,Objective C,Ios,Xcode,Ios Simulator,Objective C Blocks,还有人对XCode 4.2(lion)或4.0.2中的4.3 iPhone模拟器有问题吗 我有一些代码长期以来一直在工作、测试,并在生产中使用块来指定完成操作。例如,我使用UIView animate淡出标签顶部的一些文本,如下所示: [UIView animateWithDuration: 0.0 delay: 0.0 options: (UIViewAnimationOptionCurveEaseInOu

还有人对XCode 4.2(lion)或4.0.2中的4.3 iPhone模拟器有问题吗

我有一些代码长期以来一直在工作、测试,并在生产中使用块来指定完成操作。例如,我使用UIView animate淡出标签顶部的一些文本,如下所示:

[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\u BAD\u访问权限——设备上从来没有问题

在另一个地方,我使用自己的完成块实现在用户取消模式视图后采取操作

    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,并且analyzer运行正常。此外,该代码已投入生产6个月,没有崩溃


还有谁有这个问题吗?这是我升级XCode后发生的。

据我所知,这是一个只影响4.3模拟器的已知问题。4.2版和5.0版之前的版本似乎没有出现这个问题。然而,现在Lion已经出局了,这是一个更大的问题,因为最新的Xcode通用发行版只支持4.3模拟器,而这正是问题所在

实际原因在于块和ObjC运行时之间的挂钩。块本身可以正常工作,但任何试图调用其上的Objective-C消息的尝试都将导致segfault。这是因为块运行时包含了两个未初始化的相关Objc类的引用,而在IOS 4.3模拟器上,Objc运行时加载时,它们从不被初始化(它们仅在Objc被使用时被初始化),所以块运行时不依赖于基础加载。您可以在运行时通过查看调试器中的
\nsconcretepackblock
\NSConcreteGlobalBlock
\nsconcretemallock
的值来检查这一点。在4.2模拟器或设备上,这些值将为非零,但在4.3模拟器上仍然为零

我有一个潜在的解决方案,如果必要的话,我会链接到这里,但首先我会尝试从苹果那里挤出一些信息,比如他们是否在发布的尖端有一个补丁,或者他们是否需要更多的信息,等等

更新:问题已解决

我做了大量的挖掘,最终归结为:不要使用
-weake\u library
对libSystem.dylib进行弱链接。相反,您要么根本不应该使用弱链接libSystem(我在支持iOS 3.1.x时必须这样做,因为编译器在某些iOS4特定条件代码中生成的块代码在启动时导致了链接错误,即严重崩溃),要么应该改为使用
-weak lSystem
,模拟器更能理解这一点

在iOS模拟器中运行时,您可以查看加载的库(在Xcode中:“产品->调试->共享库…”),如果搜索“块”,您将看到两个项目:
libsystem\u Blocks.dylib
libsystem\u sim\u Blocks.dylib
。后者是由CoreFoundation链接的,它为Blocks运行时初始化ObjC运行时胶水。但是,由于您将
libSystem
库作为一个整体进行弱链接,通常由模拟器版本覆盖的符号(因为它加载的时间晚于libSystem)实际上在运行时从实现它们的第一个库被覆盖。这意味着您将找到
\NSConcreteGlobalBlock
和friends的系统版本,它们不是由模拟器的自定义ObjC运行时初始化的


关于这个问题的(很多!)更多信息,以及我是如何追踪的,请查看我制作的线程。

Update——我在另一个代码领域发现了这个问题,其共同点似乎是我使用块来指定以后会发生什么。我创建了一个类似的函数,它在模态视图中请求一个值,然后在选择该值后执行两个方法:我有相同的问题,没有解决方案。糟透了,你有没有收到苹果公司的消息?这是一个令人沮丧的问题,尤其是当你使用更新版本的Xcode时,你甚至无法访问以前的模拟器版本来解决这个问题。我在最新的模拟器上也得到了这个问题,即使这些对象不是零。以防没有人收到关于我上面编辑的通知:我解决了它,这是一个简单的修复。我的答案经过编辑,包括了细节。感谢您的挖掘,这已经困扰了我们一段时间,现在变得至关重要,因为最新版本的Xcode没有4.3模拟器,这也破坏了5.0模拟器。简单地说,我们需要做的是:1。在项目生成设置编辑器中的“链接”标题下,查找“其他链接器标志”。2.它将包含
-weak_library
-all_load
-ObjC
的条目。3.单击
-weak_library
的条目,并将其替换为
-weak lSystem
。4.瞧!值得一提的是,ApacheCordova1.7(又名Phonegap)在其模板生成的项目中存在这个问题。我和他们一起记录了一个bug报告()