NSAssert в NSXMLParser делегат не перехватывается - PullRequest
0 голосов
/ 23 ноября 2010

Я новичок в разработке для iPhone / Objective-C, я успешно разбираю XML с NSXMLParser, но не могу получить исключения для правильной работы.Я хотел бы использовать исключения для работы с неожиданным XML.

Я обертываю код для создания NSXMLParser объекта и отправляю setDelegate и анализирую сообщения для объекта внутри @try @catchblock, перехватывая @NSException.

Если я поместил NSAssert(FALSE, @"error) в блок @try, исключение будет перехвачено правильно.Однако, если у меня произошел сбой NSAssert внутри вызовов делегата (например, didStartElement, didEndElement, foundCharacters), то программа умирает (в iPhone Simulator еще не пробовал устройство).Трассировка стека отладчика показывает, что утверждение было преобразовано в исключение, но не возвращается в код верхнего уровня, где блок @try находится вокруг вызова сообщения [parser parse].Вместо этого я получаю «Завершение приложения из-за необработанного исключения».

Пожалуйста, дайте мне знать, если это известная проблема или я делаю что-то глупое здесь.

Спасибо - Алекс

Некоторый код, чтобы сделать более конкретным;нет попыток исправить этот код для памяти / выпусков / и т.д.

@implementation XMLTester

+(void)runXMLTester
{
    BOOL success = FALSE;
    XMLTester *tester = [[XMLTester alloc] init];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=KSFO"]];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:tester];
    @try {
        //NSAssert(FALSE, @"error"); // this assertion works fine
        success = [parser parse];
    }
    @catch (NSException * e) {
        success = FALSE;
        NSLog(@"Exception caught %@: %@", [e name], [e reason]);
    }
    @finally {
        NSLog(@"runXMLTester @finally block hit");
    }
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"Starting element %@", elementName);
    NSAssert(FALSE, @"error"); // this assertion does not work - does not hit @try block around parse message
}

Ответы [ 2 ]

0 голосов
/ 23 ноября 2010

Не используйте исключения для управления потоком. Написание безопасного для исключений (пересчитанного) кода Obj-C - это немного сложно & mdash; в частности, часто используемые вещи, такие как Foo * foo = [[Foo alloc] init]; [foo doStuff]; [foo release]; foo = nil;, будут пропускать, а [foo lock]; [foo doStuff]; [foo unlock];, вероятно, будут тупиковыми. Вы можете уменьшить первое, всегда выпуская автоматическое освобождение немедленно (я всегда делаю это для предотвращения утечек памяти при рефакторинге кода), за исключением того, что вы не можете автоматически освобождать пулы автоматического освобождения. Последнего трудно избежать, если вы не посыпаете @ try / @ finally везде .

Кроме того, я настоятельно рекомендую точку останова objc_exception_throw (). Иногда кажется, что Xcode пропускает бросок и бросает вас в отладчик, когда abort () вызывается из uncaught_exception_handler () (или как там его называют) после того, как стек бесполезно разматывался. И некоторые вещи (особенно CoreAnimation) перехватывают, регистрируют и иным образом игнорируют исключения, что затрудняет отладку, если вы не смотрите длинный.

В приложении есть один случай, когда я использовал исключение для потока управления (кажется, я дал ему имя «ControlThrow»); каждый раз, когда я достигаю этой точки останова, я испытываю желание заменить ее на goto.

0 голосов
/ 23 ноября 2010

Согласно Биллу Бумгарнеру , перехват исключений в симуляторе iPhone работает неправильно.Лучше всего прекратить использовать исключения здесь, так как в любом случае это не совсем уместно.Вы должны звонить -[NSXMLParser abortParsing] вместо.

...