【问题标题】:how do I catch a NSRangeException?如何捕获 NSRangeException?
【发布时间】:2010-08-07 20:53:58
【问题描述】:

我希望我的应用程序在在线服务器出现故障时能够正常运行。我试图将危险线包裹在@try 块中。然而它仍然像这样崩溃:

方法:

+ (NSArray *)findAllFor:(NSObject *)ratable {
      NSString *ratingsPath = [NSString stringWithFormat:@"%@%@/%@/%@%@",
     [self getRemoteSite],
     [ratable getRemoteCollectionName],
     [ratable getRemoteId],
     [self getRemoteCollectionName],
     [self getRemoteProtocolExtension]];

     Response *res = [ORConnection get:ratingsPath withUser:[[self class] getRemoteUser] 
     andPassword:[[self class] getRemotePassword]];
     NSArray *ratings;
     @try {
          ratings = [self fromXMLData:res.body];
     }
     @catch (NSException *e) {
          ratings = [NSArray array];
     }
    return ratings;
}

堆栈跟踪:

节目接收信号:“SIGABRT”。 2010-08-07 16:38:51.846 TalkToHer[68608:7003] *** 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“***-[NSArray objectAtIndex:]:索引 1 超出范围 [0 .. 0]' *** 第一次抛出调用堆栈: ( 0 核心基础 0x02932919 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x02a805de objc_exception_throw + 47 2 核心基础 0x0292858c -[__NSArrayI objectAtIndex:] + 236 3 TalkToHer 0x00009fa7 -[FromXMLElementDelegate 解析器:didEndElement:namespaceURI:qualifiedName:] + 425 4 基础 0x0017bcc1 _endElementNs + 453 5 libxml2.2.dylib 0x02d9deb6 xmlParseXMLDecl + 1353 6 libxml2.2.dylib 0x02da8bc1 xmlParseChunk + 3985 7 基础 0x0017b4c2 -[NSXMLParser 解析] + 321 8 TalkToHer 0x0000b14d +[NSObject(XMLSerializableSupport) fromXMLData:] + 201 9 TalkToHer 0x00031a6c +[评级 findAllFor:] + 320 10 TalkToHer 0x00032d67 -[FirstClassContentPiece(Ratable) updateRatings] + 96 11 TalkToHer 0x00004d5f __-[InspirationController tableView:didSelectRowAtIndexPath:]_block_invoke_3 + 33 12 libSystem.B.dylib 0x9792efe4 _dispatch_call_block_and_release + 16 13 libSystem.B.dylib 0x97921a4c _dispatch_queue_drain + 249 14 libSystem.B.dylib 0x979214a8 _dispatch_queue_invoke + 50 15 libSystem.B.dylib 0x979212be _dispatch_worker_thread2 + 240 16 libSystem.B.dylib 0x97920d41 _pthread_wqthread + 390 17 libSystem.B.dylib 0x97920b86 start_wqthread + 30 ) 在抛出“NSException”实例后调用终止

我的@try @catch 语法错了吗?我试图为NSRangeException 添加一个@catch 块,但这似乎不是正确的方法(它不是一个类)。

另外,服务器错误是由[ratable getRemoteId] 有时返回(null) 而不是整数引起的。这种行为似乎非常不可预测。如果有人知道为什么ObjectiveResource 可能会这样做,那会很有帮助。但是我还是想知道@try @catch怎么用。

【问题讨论】:

  • 您有没有机会尝试将-[FromXMLElementDelegate parser:didEndElement:namespaceURI:qualifiedName:] 包装在@try @catch 中,就像在修复代码之前提到的@kperryua 一样?可以成功捕获NSRangeExceptions,也许是关于 Objective-C 和 C 绑定如何阻止它在堆栈中更早地到达您的代码(如果我没记错的话,libxml2 是一个 C 库)。

标签: objective-c cocoa error-handling nsexception


【解决方案1】:

根据我现在的理解,抛出异常应该只用于提醒库的用户他们犯了编程错误。我仍然很好奇为什么我使用的语法没有防止崩溃。我知道错误发生在几个级别。但是@try {} @catch {} 块应该处理我调用的方法调用的所有方法...

无论如何,这里是固定代码,适用于任何想要从 Rails 风格的 restful 资源中获取作用域对象的人。

+ (NSArray *)findAllFor:(NSObject *)ratable {
    NSString *ratingsPath = [NSString stringWithFormat:@"%@%@/%@/%@%@",
                          [self getRemoteSite],
                          [ratable getRemoteCollectionName],
                          [ratable getRemoteId],
                          [self getRemoteCollectionName],
                          [self getRemoteProtocolExtension]];

    Response *res = [ORConnection get:ratingsPath withUser:[[self class] getRemoteUser] 
                      andPassword:[[self class] getRemotePassword]];
    NSError **aError;
    if([res isError]) {
        *aError = res.error;
        return nil;
    }
    else {
        return [self performSelector:[self getRemoteParseDataMethod] withObject:res.body];
    }
}

【讨论】:

    【解决方案2】:

    你没有。在这些情况下,您可以修复代码以不引发异常。

    【讨论】:

    • 好吧,我知道异常有时在Cocoa中被视为最后的手段,但我还是想知道如何正确使用它们。特别是因为该代码是由其他人编写的 - 谁知道如果我更改它会破坏什么。
    • 不,异常被官方视为“程序员错误”。我很欣赏代码不是由您编写的,但尝试以某种方式处理异常会以泪水告终(内存管理等)。而是修复该代码。
    • (如果你看不出来,你的错误在-[FromXMLElementDelegate parser:didEndElement:namespaceURI:qualifiedName:],而不是你列出的方法。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多