这个概念似乎给我带来了麻烦.为什么NSError对象需要将其指针传递给正在修改对象的方法?例如,不仅仅是传递对错误的引用做同样的事情吗?
NSError *anError; [myObjc doStuff:withAnotherObj error:error];
然后在doStuff中:
- (void)doStuff:(id)withAnotherObjc error:(NSError *)error { // something went bad! [error doSomethingToTheObject]; }
为什么上述工作不像大多数其他对象消息传递模式一样有效?为什么必须使用错误:(NSError**)错误?
很简单:
如果将指向对象的指针传递给函数,则该函数只能修改指针指向的内容.
如果将指针传递给指向对象的指针,则该函数可以修改指针以指向另一个对象.
在NSError的情况下,该函数可能想要创建一个新的NSError对象并向您传回指向该NSError对象的指针.因此,您需要双重间接,以便可以修改指针.
该NSError**
时的方法通常返回一些值,而是可能需要返回一个错误对象(类型的使用模式NSError*
),如果它失败.在Objective-C中,方法只能返回一种类型的对象,但是这种情况下你想要返回两种.在类C语言中,当您需要返回一个额外的值时,您需要一个指向该类型值的指针,因此要返回一个NSError*
您需要一个NSError**
参数.一个更现实的例子是:
// The method should return something, because otherwise it could just return // NSError* directly and the error argument wouldn't be necessary - (NSArray *)doStuffWithObject:(id)obj error:(NSError **)error { NSArray *result = ...; // Do some work that might fail if (result != nil) { return result; } else { // Something went bad! // The caller might pass NULL for `error` if they don't care about // the result, so check for NULL before dereferencing it if (error != NULL) { *error = [NSError errorWithDomain:...]; } return nil; // The caller knows to check error if I return nil } }
如果您只有一个NSError*
参数而不是一个参数,NSError**
则doStuff
永远无法将错误对象传递回其调用者.
一个老问题,但我认为值得把它放在这里 -
实际的罪魁祸首是NSError.如果你看一下它的类引用,它的任何属性都没有setter方法,即domain,code或userInfo.所以没有办法,您可以只分配和初始化NSError,将其传递给方法,然后填充传递的NSError对象的信息.(如果有一个setter方法,我们可能刚刚传递了一个NSError*并在方法中做了类似error.code = 1的操作.)
因此,如果出现错误,您必须在方法中生成一个新的NSError对象,如果您这样做,将它传递回调用者的唯一方法是使用NSError**参数.(由于上述答案中解释的原因.)
关于n8gray所说的替代声明:
因为您没有收到要发送消息的对象; 你正在创建对象并返回它.您通常需要指向NSError *
变量的参数,因为您一次只能return
在一件事物上使用该语句,并且您已经在使用它NO
.