Использование блоков сбоев приложения в iPhone Simulator 4.3/XCode 4.2 и 4.0.2

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

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


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

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

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

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

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

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

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