如何定义返回错误和值的方法?
例如,当我调用managedObjectContext保存方法时,该方法返回一个布尔值以及一个错误:
if(![context save:&error]) {
NSLog(@"%@", error);
}
您能否给我一个直截了当的方法定义示例?
编辑/更新:同样,如何传回多个错误。我在下面做错了(我可能还不明白这个概念),这不起作用:
NSArray *errors = nil;
[self throwMultipleErrors:&errors];
for(id error in errors) {
NSLog(@"Muliple error: %@", error);
}...
-(BOOL)throwMultipleErrors:(NSMutableArray **) errors {
[*errors addObject:@"First Error"];
[*errors addObject:@"Second Error"];
[*errors addObject:@"Third Error"];
return YES;
}
答案 0 :(得分:3)
在您的示例中,方法签名为:
- (BOOL)save:(NSError **)error;
这允许调用者传入NSError
作为地址而不是指针(指向指针**
和&
的指针),然后该方法可以从另一个指定范围。如果方法返回false,则调用者可以检查错误变量的内容,如示例所示。
有关在变量和&
签名前使用(NSError **)
的详细信息,请参阅此问题。
Why is `&` (ampersand) put in front of some method parameters?
示例实施:
- (BOOL)save:(NSError **)error
{
NSAssert(error != nil, @"Passed NSError must be nil!");
// Attempt to do a save
if (saveDidFail) {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectAndKeys:@"Save Failed", kCustomErrorKey, nil];
*error = [NSError errorWithDomain:@"domain" code:999 userInfo:userInfo];
return NO;
}
return YES;
}
答案 1 :(得分:3)
使用您的示例,方法签名将是:
-(BOOL)save:(NSError**)error;
现在,当使用双指针时,你需要在编程中保持防守。首先,您必须确保error
的值不是nil
,然后*error
是nil
。您必须执行此操作,因为您不知道如何使用现有对象进行内存管理。例如:
NSError *error = nil;
[self save:&error];
是正确的。但
NSError *error = [[NSError alloc] init];
[self save:&error];
是一个问题,因为如果save:
为error
或retained
,则autoreleased
方法不会出现。如果您release
它是autoreleased
,那么您的应用最终会崩溃。相反,如果你没有release
而它是retained
你就会泄漏内存。我建议使用断言检查这一点,以便在签入代码之前快速解决问题。
NSAssert(!error || !*error, @"*error must be nil!");
最后,在设置*error
时,您必须确保error
不是nil
。永远不允许您设置内存地址0x0
的值。如果您没有检查并且是否将nil
传递给方法,那么如果您尝试设置它,将崩溃。
if (error)
{
*error = [NSError ...];
return NO;
}
要返回一个数组,我会做这样的事情:
-(BOOL)throwMultipleErrors:(NSError **) error {
NSAssert(!error | !*error, @"*error must be nil");
NSMutableArray *errorList = nil;
if (error)
errorList = [NSMutableArray array];
[errorList addObject:@"First Error"];
[errorList addObject:@"Second Error"];
[errorList addObject:@"Third Error"];
if (error && [errorList count] > 0)
{
*error = [NSError errorWithDomain:@"Some error"
code:0
userInfo:@{@"suberrors" : [NSArray arrayWithArray:errorList]}];
return NO;
}
return YES;
}
请注意,返回数组是不可变的,并在方法内实例化。这个数组之外没有理由在这个方法之外是可变的,并且数组在它之外被实例化。将数组封装在NSError
中允许它轻松地适应现有的NSError
方法链。
注释
当然,您实际上会将[self save:&error];
调用放入if()
语句中以检查返回值。但请注意,我们传递的是&error
,而不仅仅是error
。这是因为我们需要将指针传递给error
,而不是error
。 &error
读作“错误的地址。”
答案 2 :(得分:2)
我们需要在这里注意语法。 当我们将NSError传递给方法时: +(instancetype)stringWithContentsOfFile:(NSString *)路径编码:(NSStringEncoding)enc错误:(NSError * *)错误
我们将句柄(指针指针)交给尚未初始化的错误对象。如果被叫消息遇到麻烦,它将初始化并填充错误对象。它不会“返回”错误,只需将值填入传递的参数。
因此,如果我想定义一条返回值的消息,并且还需要一个错误参数,请按照以下教程操作: http://www.cimgf.com/2008/04/04/cocoa-tutorial-using-nserror-to-great-effect/