Получение EXC_BAD_ACCESS в iOS 4 с использованием dispatch_once, а не в iOS 5 - PullRequest
0 голосов
/ 28 марта 2012

Я предполагаю, что это должна быть новая функциональность, поскольку этот код не работает на моем устройстве iOS4, отлично работает на iOS5.Мне нужно это, чтобы работать на обоих.Я еще не перешел на iOS5, поскольку мне все еще нужно поддерживать iOS4, поэтому я не знаю, как это обойти?

static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{ //EXC_BAD_ACCESS
   _sharedStoreManager = [[super allocWithZone:nil] init];            
});

Это из https://github.com/MugunthKumar/MKStoreKit/blob/master/MKStoreManager.m

Ответы [ 3 ]

4 голосов
/ 28 марта 2012

dispatch_once() не является новой версией iOS 5.0, она существует с 4.0. Я все время использую его в приложениях, ориентированных на 4.0, например, в этом синглтоне из одной из моих платформ:

+ (GPUImageOpenGLESContext *)sharedImageProcessingOpenGLESContext;
{
    static dispatch_once_t pred;
    static GPUImageOpenGLESContext *sharedImageProcessingOpenGLESContext = nil;

    dispatch_once(&pred, ^{
        sharedImageProcessingOpenGLESContext = [[GPUImageOpenGLESContext alloc] init];
    });
    return sharedImageProcessingOpenGLESContext;
}

Из Документация Apple :

Наличие

Доступно в iOS 4.0 и более поздних версиях.

Я предполагаю, что ваша проблема существует в -init вашего _sharedStoreManager. Например, есть ли причина, по которой вы используете -allocWithZone: там?

2 голосов
/ 28 марта 2012

Это было вызвано ошибкой в ​​моем коде, и я исправил ее. Обновите свои подмодули. Спасибо Брэду Ларсону за уведомление.

1 голос
/ 28 марта 2012

dispatch_once доступно , и нет ничего плохого в размещенном вами фрагменте.

Я вижу две проблемы с остальным кодом, однако обе они связаны со строкой 194. Сначала менеджер отправляется init дважды: один раз внутри блока dispatch_once, а затем после в этой строке:

if(!_sharedStoreManager) {
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedStoreManager = [[super allocWithZone:nil] init];            
    });

  #if TARGET_IPHONE_SIMULATOR
    NSLog(@"You are running in Simulator MKStoreKit runs only on devices");
  #else
/*194*/_sharedStoreManager = [[self alloc] init];

Это плохая вещь.

Причиной этого, и, что более важно, является то, что это похоже на бесконечный цикл. В строке 194 вызываются +[MKStoreManager alloc], которые заканчиваются на +[MKStoreManager allocWithZone:], что снова вызывает +sharedManager!

+ (id)allocWithZone:(NSZone *)zone
{   
    return [self sharedManager];
}

Я бы не думал, что такой цикл вызовет EXC_BAD_ACCESS, но я рекомендую удалить строку 194; это неправильно.

(я бы также порекомендовал исправить отступ для блока if.)

...