Objective c 如何避免在Objective C中的每一层上出现大量错误处理代码

Objective c 如何避免在Objective C中的每一层上出现大量错误处理代码,objective-c,exception,if-statement,readability,nserror,Objective C,Exception,If Statement,Readability,Nserror,在目标C中,我如何避免在我的方法中有如此广泛的错误处理?我曾读到苹果公司建议仅在预期会出现错误时才使用NSError引用,但这种方法会导致代码完全被错误处理代码弄乱 这份文件中有一句话特别吸引我的眼球 解析库可以在内部使用异常来指示问题,并允许快速退出可能是深度递归的解析状态;但是,您应该注意在库的顶层捕获此类异常,并将其转换为适当的返回代码或状态 这是一段(不完整且未优化的)代码片段,演示了我的意思。我在方法中进行的每个调用都需要在每个步骤上进行错误检查,用if语句将代码弄乱,使其难以阅读

在目标C中,我如何避免在我的方法中有如此广泛的错误处理?我曾读到苹果公司建议仅在预期会出现错误时才使用NSError引用,但这种方法会导致代码完全被错误处理代码弄乱

这份文件中有一句话特别吸引我的眼球

解析库可以在内部使用异常来指示问题,并允许快速退出可能是深度递归的解析状态;但是,您应该注意在库的顶层捕获此类异常,并将其转换为适当的返回代码或状态

这是一段(不完整且未优化的)代码片段,演示了我的意思。我在方法中进行的每个调用都需要在每个步骤上进行错误检查,用if语句将代码弄乱,使其难以阅读

- (NSNumber) countFriendsForUserName:(NSString*) userName error:(NSError **)error {
    NSError *internalError = nil;
    Session *session = [_sessionMgr openSessionWithError:&internalError];
    if (!error) {
        User *user = [session findUserByName:userName error:&internalError];
       if (!error) {
           NSArray * bestFriends = [session getFriendsByUserId:user.id error:&internalError];
       }
    }
    [_sessionMgr closeSession];        
    if (internalError) {
        *error=internalError;
        return 0;
    } 
    return [bestFriends count];
}
如果我改为使用异常,代码看起来会像这样(同样,这段代码只是一个不完整的示例),我现在没有XCode

- (NSNumber) countFriendsForUserName:(NSString*) userName error:(NSError **)error {
    @try{
        Session *session = [_sessionMgr openSession];
        User *user = [session findUserByName:userName];
        NSArray * bestFriends = [session getFriendsByUserId:user.id];
        [_sessionMgr closeSession];  
        return [bestFriends count];            
    } 
    @catch (NSException *e) {
        [_sessionMgr closeSession];        
        *error=[ExceptionParser createNSErrorFromException:e];
        return 0;
    } 
}

如果我正确地解释了Apple异常指导原则,如果我的代码表现得像一个“解析库”(Apple示例),那么在内部使用异常并在返回调用函数之前对其进行翻译可能是完全可以的,然后调用函数可能会对我的N错误代码执行相应的操作。还是我误解了苹果的指导方针

您应该测试方法的返回值,而不是
NSError
对象的存在。您还可以链接
NSError
对象,将低级错误返回给调用者:

- (NSInteger)countFriendsForUserName:(NSString*)userName
                               error:(NSError **)error
{
    NSArray *bestFriends = nil;
    Session *session = [_sessionMgr openSessionWithError:error];
    if (session) {
        User *user = [session findUserByName:userName error:error];
        if (user) {
           bestFriends = [session getFriendsByUserId:user.id error:error];
        }
    }
    [_sessionMgr closeSession];
    return [bestFriends count];
}
注:

  • bestFriends
    移至方法顶部
  • 更改了返回类型

你打字比我快;)这些都是非常正确的观点。但我还是很好奇,为什么例外情况不是更好?代码根本不需要任何if语句,在最后一步,在将结果返回给应用程序(和用户)之前,异常将被转换为应用程序用户界面可以解释的N错误。对于异常情况,应使用异常。如果一个方法返回一个值,并且返回的值是
NO
nil
或其他任何值,那么这不一定是一个错误。这仅仅意味着正在寻找的东西不存在,如果您想知道是否需要添加该东西,这不是一个错误。在细粒度级别处理异常也非常昂贵和麻烦。还要注意的是,ARC不是异常安全的。如果抛出异常,将泄漏ObjC中的内存。这通常是正常的,因为预计在抛出异常后不久将崩溃。《异常处理指南》中的指南早于ARC。如果编译为ObjC++(或者将某些标志传递给编译器),将出现内存安全异常,但这会影响性能(内存和时间),因此不鼓励这样做。