質問

Xcode 4.3

I've read the SO questions on NSError**, so I wrote a simple test program that uses a slightly different syntax recommended by Xcode 4.3 (see __autoreleasing below), so I'm not 100% sure if this is correct, although the code does appear to function properly. Anyway, just a simple file reader, prints an error if the file can't be found.

Questions

Would like to know if the NSError initialization, argument passing using &, and error condition checking are correct. Also, in the readFileAndSplit.. method, I noticed a big difference between if(!*error) and if(!error), in fact, if(!error) does not work when no error condition is raised.

File Reading Method w/Possible Error Condition

 -(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;

Caller

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

if(fileError){
  NSLog(@"Error was : %@, with code: %li", 
       [fileError localizedDescription],(long)[fileError code]);
} 
役に立ちましたか?

解決

There are a couple of issues.

First, As per Apple's Error Handling Programming Guide, you should be checking a method's return value to determine whether a method failed or not, and not NSError. You only use NSError to get additional error information in the event that the method failed.

E.g.:

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

return fileContentsAsArray; // may be nil

Second, NSError out parameters are typically optional and may be NULL. But if you pass a NULL error variable into your method it will crash on this line:

if (!*error) { 

because you're dereferencing a NULL pointer. Instead, you must always check for NULL before referencing a pointer, like so:

if (error && *error) 
{
    // Do something with the error info
}

However, if you rewrite the method as indicated above then you won't be accessing the error variable at all.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top