Использование NSAssert в потоках - PullRequest
5 голосов
/ 06 января 2010

Я пытаюсь использовать NSAssert во всем приложении для iPhone, чтобы в случае непредвиденного состояния приложение быстро сбойно и вылетало со значимым сообщением в журнале сбоев.

Это прекрасно работает, если сбойный NSAssert находится в главном потоке, так как он поднимает NSInternalInconsistencyException по умолчанию, что отключает и останавливает выполнение. Но я также делаю обработку в фоновых потоках, в этом случае NSAssert просто прерывает поток, но программирование продолжает выполняться.

Мое текущее решение состоит в том, чтобы перехватить и перебросить исключение в главном потоке (в данном случае, метод NSOperation main):

- (void)main {
    @try {
        int x = 14;
        ...
        NSAssert1(x > 20, @"x should be greater than 20, was %d", x);
        ...
    }
    @catch (NSException *e) {
        [e performSelectorOnMainThread:@selector(raise) withObject:nil waitUntilDone:YES];
    }
}

Есть ли лучший способ? Возможно, с помощью пользовательского NSAssertionHandler?

Я знаю, что мог бы просто использовать C assert со статической аннотацией:

assert(x > 20 && "x should be greater than 20");

Но это не позволяет мне показать, каково действительное ошибочное значение x.

1 Ответ

1 голос
/ 07 января 2010

Вы можете заменить NSAssert тестовым кодом с последующим повышением исключения. Таким образом, если утверждение не удалось, будет сгенерировано исключение, перехваченное блоком @catch и повторно вызванное в основном потоке.

Примечание: Вы можете даже определить макрос C, чтобы обеспечить компактную форму.

...