Сохранить счет исчерпан после @throw - PullRequest
0 голосов
/ 06 марта 2012

Когда я запускаю этот код внутри вызова, сделанного из SenTest's STAssertThrowsSpecificNamed:

@throw [[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                  reason:@"---some reason----"
                               userInfo:nil];

, я получаю (с NSZombieEnabled=YES):

*** -[NSException reason]: message sent to deallocated instance 0x100a81d60

Исключение как-то освобождаетсядо того, как STAssertThrowsSpecificNamed завершит его обработку.

Я могу избежать этой ошибки, заменив строку @throw выше следующим кодом:

NSException *exception = [NSException exceptionWithName:NSInvalidArchiveOperationException
                                                 reason:@"---some reason----"
                                               userInfo:nil];
@throw exception;

Я получаю точно такое же поведение с или безARC.Без ARC этот код также позволяет избежать ошибки:

@throw [[[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                   reason:@"---some reason----"
                                userInfo:nil] retain];

Это ошибка в SenTest?Или ошибка в компиляторе?Или мой первый @throw просто неверен?

Ответы [ 3 ]

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

@ throw освобождает объект после его использования, поэтому используйте -retain, если вы хотите включить его в ту же строку, что и @ throw.

@throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                  reason:@"---some reason----"
                               userInfo:nil] retain] autorelease];

Это должно сработать.

РЕДАКТИРОВАТЬ: Чтобы проверить код, специфичный для ARC, используйте:

if(__has_feature(objc_arc)) {
    @throw [[[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                       reason:@"---some reason----"
                                     userInfo:nil];
} else {
    @throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                      reason:@"---some reason----"
                                   userInfo:nil] retain] autorelease];
}
1 голос
/ 18 мая 2013

Я сейчас использую исключительно +[NSException raise:format:] как для ARC, так и для ручного удержания-выпуска.

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

Пока что я придерживаюсь этой формы, которая, кажется, работает, и с ARC и без нее .

id exc = [NSException exceptionWithName:NSInvalidArchiveOperationException
                                 reason:@"---some reason----"
                               userInfo:nil];
@throw exc;

Согласно ответу Galaxas0, @throw предназначен для освобождения исключения после его обработки. Это до сих пор кажется мне странным, особенно при ARC.

В проекте не-ARC используйте это (также для Galaxas0):

@throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException
                                    reason:@"---some reason----"
                                  userInfo:nil] retain] autorelease];
...