Использование приложения Blocks crashes в iPhone Simulator 4.3 / XCode 4.2 и 4.0.2 - PullRequest
7 голосов
/ 19 июля 2011

У кого-нибудь еще есть проблемы с симулятором iPhone 4.3 в XCode 4.2 (лев) или 4.0.2?

У меня есть код, который долгое время работал, тестировался, и в производстве, который использует блоки для определения действий по завершению. Например, я использую анимацию 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.

1 Ответ

22 голосов
/ 10 августа 2011

Насколько я знаю, это известная проблема, которая касается только симулятора 4.3.Версии 4.2 и prerelease 5.0, похоже, не демонстрируют эту проблему.Однако теперь проблема заключается в том, что Lion вышел, потому что последняя версия Xcode общего выпуска поддерживает только симулятор 4.3, где эта проблема возникает.

Фактическая причина заключается в перехватах между блоками исполнения и ObjC.Сами блоки будут работать очень хорошо, но любая попытка вызвать для них сообщение Objective-C приведет к ошибке.Это связано с тем, что среда выполнения Blocks содержит несколько неинициализированных ссылок на соответствующие классы ObjC, а на симуляторе iOS 4.3 они никогда не инициализируются при загрузке среды выполнения ObjC (они инициализируются только в том случае, если ObjC вообще используется - таквремя выполнения блоков не зависит от загрузки Foundation).Вы можете проверить это во время выполнения, посмотрев на значения для _NSConcreteStackBlock, _NSConcreteGlobalBlock и _NSConcreteMallocBlock в отладчике.В симуляторе 4.2 или на устройстве эти значения будут отличны от нуля, но на симуляторе 4.3 они по-прежнему равны нулю.

У меня есть потенциальное решение, на которое я буду ссылаться при необходимости, но сначалаЯ собираюсь попробовать и выжать из Apple некоторую информацию о том, есть ли у них исправления на пороге релиза или им нужна дополнительная информация и т. Д.

ОБНОВЛЕНИЕ: ПРОБЛЕМА РЕШЕНА

Я много копал, и в конечном итоге все сводится к следующему: не используйте слабые ссылки на libSystem.dylib, используя -weak_library.Вместо этого вы вообще не должны использовать libSystem со слабыми ссылками (я должен был это делать при поддержке iOS 3.1.x, потому что сгенерированный компилятором код Blocks в каком-то условном коде, специфичном для iOS4, вызывал ошибку ссылки во время запуска, т.е.), или вы должны использовать -weak lSystem вместо этого, что Симулятор понимает лучше.

Когда вы работаете в iOS Simulator, вы можете посмотреть загруженные библиотеки (в Xcode: 'Product-> Debug-> Общие библиотеки… '), и если вы будете искать «Блоки», вы увидите два элемента: libsystem_blocks.dylib и libsystem_sim_blocks.dylib.Последний связан с CoreFoundation, который инициализирует клей времени выполнения ObjC для среды исполнения Blocks.Однако, поскольку вы слабо связываете библиотеку libSystem в целом, символы, которые обычно переопределяются версией симулятора (поскольку она загружается позже, чем libSystem), фактически перезаписываются во время выполнения из first библиотека, которая их реализует.Это означает, что вы найдете system версии _NSConcreteGlobalBlock и друзей, которые были , а не , инициализированными пользовательской средой выполнения ObjC Simulator.

For (много!) больше информации о проблеме, и чтобы увидеть, как я ее выследил, посмотрите ветку, которую я сделал на форумах разработчиков Apple .

...