为什么这里使用的是“error:&error”(objective-c)
为什么这里使用的是“error:&error”(objective-c)
NSError *error = nil; NSArray *array = [moc executeFetchRequest:request error:&error];
客观的c中的对象不会有效地通过引用吗?
error:
的参数types是NSError**
(即指向对象的指针)。 这允许moc
对象根据需要分配和初始化一个新的NSError
对象。 这是一个常见的模式,尤其是在cocoa。
NSError文档给出了这种方法的动机的一些迹象:
应用程序可以select创buildNSError的子类,以通过重写localizedDescription来提供更好的本地化错误string。
传递一个NSError**
参数允许该方法返回任何有意义的NSError
子类。 如果你通过了NSError*
,你将不得不提供一个已经存在的NSError
对象,并且这个方法没有办法从你传入的对象中返回一个不同的对象。
要清楚的是,该方法可能看起来像这样:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError**)error { ... if ((error != NULL) && (some_error_condition)) { *error = [[[SomeNSErrorSubclass alloc] init...] autorelease]; return nil; } }
请注意,这也允许调用代码忽略错误,只需传入NULL
作为error:
参数,如下所示:
NSArray *array = [moc executeFetchRequest:request error:NULL];
更新:(回答问题):
为什么参数types必须是NSError**
而不是NSError*
有两个原因:1.variables范围规则,以及2. NSError实例是不可变的。
原因#1:variables范围规则
让我们假设函数声明是这样的:
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error;
我们要这样调用函数:
NSError * error = nil; [someArray executeFetchRequest:someRequest error:error]; if (error != nil) { /* handle error */ }
当你以这种方式传递variables时,函数体将无法修改该variables的值 (即函数体将无法创build新的variables来replace现有的variables)。 例如,下面的variables赋值只存在于函数的本地范围中。 调用代码仍然会看到error == nil
。
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error { ... error = [[[NSError alloc] init...] autorelease]; // local only error = [[[SomeNSErrorSubclass alloc] init...] autorelease]; // local only }
原因#2:NSError的实例是不可变的
让我们保持相同的函数声明,但像这样调用函数:
NSError * error = [[[NSError alloc] init...] autorelease]; [someArray executeFetchRequest:someRequest error:error]; if (error != nil) { /* handle error */ }
首先,variables范围规则保证error
不能nil
,所以if (error != nil) { ...
condition总是成立的,但即使你想检查if
块内的具体错误信息,因为NSError
实例是不可变的 ,所以你会不走运。 这意味着一旦创build它们,就不能修改它们的属性,所以函数将无法更改您在调用代码中创build的NSError
实例的domain
或userInfo
。
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error { ... error.domain = ... // not allowed! error.userInfo = ... // not allowed! }
这实际上是另一个回报价值。 当有可操作的返回值时,Cocoa中的这个错误并不占优势。 遇到错误时,可能会由此输出参数返回给您。
在NSError
的情况下,它是这样工作的,因为NSError
不是一个可变types – 它的字段在初始化时被设置,并且从不变异。 因此,你不能照常传递NSError
并设置错误代码。