在iPhone Simulator 4.3/XCode 4.2和4.0.2中使用块崩溃应用程序 [英] Use of Blocks crashes app in iPhone Simulator 4.3/XCode 4.2 and 4.0.2

查看:76
本文介绍了在iPhone Simulator 4.3/XCode 4.2和4.0.2中使用块崩溃应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

还有其他人在XCode 4.2(lion)或4.0.2中使用4.3 iPhone Simulator遇到麻烦吗?

Anybody else having trouble with the 4.3 iPhone Simulator in XCode 4.2(lion) or 4.0.2?

我有长期使用,测试和在生产环境中使用块指定完成动作的代码.例如,我使用UIView动画来淡出标签顶部的一些文本,如下所示:

I have code that has long been working, tested, and in production that uses blocks to specify completion actions. For example, I use UIView animate to fade out some text on top of the label as follows:

[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-从来没有设备上的问题.

I reliably get EXEC_BAD_ACCESS in the simulator -- never a problem on the device.

在另一个地方,我使用自己的完成块实现在用户关闭模式视图后采取行动.

In another place I use my own completion block implementation to take action after the user has dismissed a modal view.

    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个月,没有崩溃.

There are no NSZombies showing up, and analyzer runs clean. Plus this code has been in production for 6 months with no crashes.

还有其他麻烦吗?自从我升级XCode以来,这种情况一直在发生.

Anybody else having this trouble? It's been happening since I upgraded XCode.

推荐答案

据我所知,这是一个已知问题,仅影响4.3模拟器. 4.2和预发行版5.0版本似乎没有出现此问题.但是,Lion出局现在是一个更大的问题,因为最新的Xcode通用发行版仅支持发生此问题的4.3模拟器.

As far as I'm aware, it's a known problem which only affects the 4.3 simulator. The 4.2 and prerelease 5.0 versions don't appear to exhibit this problem. However it's more of an issue now that Lion is out because the latest general release version of Xcode only supports the 4.3 simulator, where this problem occurs.

实际原因是在Blocks和ObjC运行时之间的挂钩中.块本身可以正常工作,但是任何在其上调用Objective-C消息的尝试都将导致段错误.这是因为Blocks运行时包含对相关ObjC类的几个未初始化的引用,并且在iOS 4.3模拟器上,当ObjC运行时加载时这些从未被初始化(它们仅在完全使用ObjC时才被初始化-因此Blocks运行时不依赖于已加载Foundation).您可以在运行时通过在调试器中查看_NSConcreteStackBlock_NSConcreteGlobalBlock_NSConcreteMallocBlock的值来进行检查.在4.2模拟器或设备上,这些值将为非零,但在4.3模拟器上,这些值仍为零.

The actual cause is in the hooks between the Blocks and ObjC runtimes. Blocks themselves will work just fine, but any attempt to call an Objective-C message on them will result in a segfault. This is because the Blocks runtime contains a couple of uninitialized references to the relevant ObjC classes, and on the iOS 4.3 simulator these are never been initialized when the ObjC runtime loads (they're only initialized if ObjC is being used at all-- so the Blocks runtime doesn't depend on having Foundation loaded). You can check this at runtime by looking at the value for _NSConcreteStackBlock, _NSConcreteGlobalBlock and _NSConcreteMallocBlock in the debugger. In the 4.2 simulator or on the device, these values will be non-nil, but on the 4.3 simulator they're still zero.

我有一个潜在的解决方案,如有必要,可以将其链接到此处,但首先我将尝试&从苹果那里榨取一些信息,以确定它们是否可以解决发行的风口浪尖,或者是否需要更多信息,等等.

I have a potential solution which I will link to here if necessary, but first I'm going to try & squeeze some information out of Apple as to whether they have a fix on the cusp of release or if they need some more info, etc.

更新:已解决问题

我做了很多挖掘工作,最终归结为:不要使用-weak_library 对libSystem.dylib进行弱链接.相反,您根本不应该弱链接libSystem(我必须在支持iOS 3.1.x时必须这样做,因为某些iOS4特定条件代码中编译器生成的Blocks代码在启动时会导致链接错误,即严重的严重崩溃),或者您应该改用-weak lSystem,模拟器会更好地理解它.

I did lots of digging, and it ultimately boils down to this: don't weak-link against libSystem.dylib using -weak_library. Instead, you should either not weak-link libSystem at all (I had to when supporting iOS 3.1.x, because compiler-generated Blocks code in some iOS4-specific conditional code was causing a link error at launch time, i.e. a bad bad crash), or you should use -weak lSystem instead, which the Simulator understands better.

在iOS模拟器中运行时,您可以查看已加载的库(在Xcode中:"Product-> Debug-> Shared Libraries…"),如果您搜索"Blocks",则会看到两个项目:libsystem_blocks.dyliblibsystem_sim_blocks.dylib.后者是由CoreFoundation链接的链接,后者为Blocks运行时初始化ObjC运行时胶水.但是,由于要整体链接libSystem库,通常在运行时会从 first 实现它们的库.这意味着您将找到和朋友的系统版本,而不是由模拟器的自定义ObjC运行时初始化的版本.

When you're running in the iOS Simulator, you can look at the loaded libraries (in Xcode: 'Product->Debug->Shared Libraries…') and if you search for 'Blocks' you'll see two items: libsystem_blocks.dylib and libsystem_sim_blocks.dylib. The latter is the one linked by CoreFoundation, which initializes the ObjC runtime glue for the Blocks runtime. However, since you're weak-linking the libSystem library as a whole, the symbols which are normally overridden by the Simulator's version (since it loads later than libSystem) are actually overwritten at runtime from the first library which implements them. This means that you'll find the system versions of _NSConcreteGlobalBlock and friends, which were not the ones initialized by the Simulator's custom ObjC runtime.

对于(很多!)有关该问题的更多信息,以及查看我如何对其进行跟踪,请查看我制作的线程在Apple开发者论坛上.

For (lots!) more information on the problem, and to see how I tracked it down, check out the thread I made on the Apple Developer Forums.

这篇关于在iPhone Simulator 4.3/XCode 4.2和4.0.2中使用块崩溃应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆