如何使用 NSError 初始化、传递参数和检查错误条件**

Posted

技术标签:

【中文标题】如何使用 NSError 初始化、传递参数和检查错误条件**【英文标题】:How to initialize, pass argument, and check error condition using NSError** 【发布时间】:2012-09-24 01:00:23 【问题描述】:

Xcode 4.3

我已经阅读了关于 NSError** 的 SO 问题,所以我编写了一个简单的测试程序,它使用了 Xcode 4.3 推荐的稍微不同的语法(参见下面的__autoreleasing),所以我不能 100% 确定这是否是正确的,尽管代码似乎运行正常。无论如何,只是一个简单的文件阅读器,如果找不到文件,则会打印错误。

问题

想知道 NSError 初始化、使用& 传递的参数和错误条件检查是否正确。 另外,在readFileAndSplit.. 方法中,我注意到if(!*error)if(!error) 之间有很大的不同,实际上if(!error) 在没有引发错误条件时不起作用。

可能出现错误情况的文件读取方法

 -(NSArray*) readFileAndSplitLinesIntoArray:(NSError *__autoreleasing *) error 
    NSString* rawFileContents =
          [NSString stringWithContentsOfFile:@"props.txt"
                                    encoding:NSUTF8StringEncoding    
                                       error:error
    NSArray* fileContentsAsArray = nil;  
    if(!*error)
          fileContentsAsArray = 
                [rawFileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    return fileContentsAsArray;

来电者

SimpleFileReader* reader = ...
NSError* fileError = nil;
NSArray* array = [reader readFileAndSplitLinesIntoArray: &fileError];

if(fileError)
  NSLog(@"Error was : %@, with code: %li", 
       [fileError localizedDescription],(long)[fileError code]);
 

【问题讨论】:

我唯一要改变的是测试rawFileContents 是否为nil,而不是是否存在错误。在 Cocoa 中,主返回值应该表示成功或失败,如果我没记错的话,当方法成功时,不能保证错误不存在。 好的,好点,但是在检查错误时,if(!*error) 是否正确?我发现这适用于readFile... 方法中的错误和非错误条件。我正在取消对双指针的引用,如果它不为空,那么就出了问题,我假设这是正确的检查方法。 我会像你一样做。 除了达伦对NULL 支票的看法是正确的 【参考方案1】:

有几个问题。

首先,根据Apple's Error Handling Programming Guide,您应该检查方法的返回值以确定方法是否失败,而不是 NSError。如果方法失败,您只使用 NSError 来获取额外的错误信息。

例如:

NSArray* fileContentsAsArray = nil;
NSString* rawFileContents = [NSString stringWithContentsOfFile:@"props.txt"
                                encoding:NSUTF8StringEncoding    
                                   error:error];
if (rawFileContents)

    // Method succeeded
    fileContentsAsArray = [rawFileContents ...];


return fileContentsAsArray; // may be nil

其次,NSError 输出参数通常是可选的,可能为 NULL。但是如果你将一个 NULL 错误变量传递给你的方法,它将在这一行崩溃:

if (!*error)  

因为您要取消引用 NULL 指针。相反,您必须始终在引用指针之前检查 NULL,如下所示:

if (error && *error) 

    // Do something with the error info

但是,如果您按照上述方法重写该方法,那么您将根本不会访问错误变量。

【讨论】:

有道理,但对一件事感到困惑。在调用者中,我初始化 NSError fileError = nil 并将其传递给 readFile...&fileError 但无论文件是否加载,if(!*error) 永远不会引发 BAD ACCESS,它总是按预期工作......我错过了什么吗? 您正在传递一个指向您的 fileError 变量的指针,并且该指针始终是非空的(无论 fileError 的值如何)。相反,请尝试不传入任何变量,例如[reader readFileAndSplitLinesIntoArray:NULL] 好点(双关语),该死的指针很棘手,谢谢你的信息

以上是关于如何使用 NSError 初始化、传递参数和检查错误条件**的主要内容,如果未能解决你的问题,请参考以下文章

无法使用类型为“(设备:AVCaptureDevice!,错误:inout NSError?)”的参数列表调用类型“AVCaptureDeviceInput”的初始化程序

无法将类型 (PFUser!, NSError) void 的值转换为预期的参数类型 PFUserResultBlock

如何检查传递给函数的参数数量是不是错误

如何始终从 NSError 获取英文字符串?

在 CloudKit 中检查/比较 NSError 代码?

Flex:传递函数和检查参数