2010-07-01 2 views
2

Я нашел сбой в приложении iPhone с целевой iOS 4, который изменяется в зависимости от типа сборки.Использование ivar в блоке, возвращенном другому объекту

отладчик не дает мне ничего особенного, чтобы идти дальше, он останавливается на

UIViewController *result = [self factory](self); 

с EXC_BAD_ACCESS. self - класс, наследующий от NSObject (показан ниже как NSObjectInheritor). Зомби включены. Я попытался изменить метод factory тремя способами со следующими результатами.

Это происходит сбой в обоих отладки и специальной сборки ...

- (FactoryMethod) factory; 
{ 
    return [^ UIViewController * (NSObjectInheritor *newThing) 
    { 
     return [[ViewControllerClass alloc] initWithStuff:(boolValue ? foo : bar)]; 
    } autorelease]; 
} 

Это работает в отладочной версии, но сбои в специальной ...

- (FactoryMethod) factory; 
{ 
    return [^ UIViewController * (NSObjectInheritor *newThing) 
    { 
    if(boolValue) 
    { 
     return [[ViewControllerClass alloc] initWithStuff:foo]; 
    } 
    else 
    { 
     return [[ViewControllerClass alloc] initWithStuff:bar]; 
    } 
    } autorelease]; 
} 

Это работает в обоих отладки и объявления специальная но очень некрасиво и излишним:

- (FactoryMethod) factory; 
{ 
    if(boolValue) 
    { 
    return [^ UIViewController * (NSObjectInheritor *newThing) 
    { 
     return [[ViewControllerClass alloc] initWithStuff:foo]; 
    } autorelease]; 
    } 
    else 
    { 
    return [^ UIViewController * (NSObjectInheritor *newThing) 
    { 
     return [[[ViewControllerClass alloc] initWithStuff:bar]; 
    } autorelease]; 
    } 
} 

Моя теория, что boolValue становится INAC в момент выполнения возвращенного блока. Это

@interface SubclassOfNSObjectInheritor : NSObjectInheritor 
{ 
    BOOL boolValue; 
} 

@property (readonly) BOOL boolValue; 

(YES или NO назначены в инициализации SubclassOfNSObjectInheritor в конечно) и

@synthesize boolValue; 

в реализации SubclassOfNSObjectInheritor в.

Окончательные вопросы - это моя теория о том, что неправильно правильно? Это третий способ сделать это - отметил, что он работает в специальных и отладочных сборках - безопасен? Каков наилучший способ сделать это?

ответ

6

Ваша проблема двоякая: сначала вы перевыполняете свой блок, а во-вторых, в стеке создаются блоки, которые исчезают, когда возвращается ваш метод (вы в основном возвращаете указатель на ранее поврежденный стек стека).

Вместо этого скопируйте блок и автоматически отпустите его перед возвратом. Вы можете сделать это объективно с помощью сообщения copy, и вы можете вызвать функцию Block_copy().

Ваш сбой в различных конфигурациях - это просто случайность. Итак, чтобы исправить одну из ваших реализаций:

- (FactoryMethod) factory; 
{ 
    return [[^(NSObjectInheritor *newThing) 
    { 
    if(boolValue) 
    { 
     return [[ViewControllerClass alloc] initWithStuff:foo]; 
    } 
    else 
    { 
     return [[ViewControllerClass alloc] initWithStuff:bar]; 
    } 
    } copy] autorelease]; 
} 
+0

Хороший ответ. Обратите также внимание на то, что «Build and Analyze» должен был поймать эту конкретную ошибку. Если это не так, напишите ошибку. – bbum

+0

Спасибо - анализатор не жалуется, так что залогиньте ошибку. Проблема с копированием. –

Смежные вопросы