使用您的示例,方法签名将是:
-(BOOL)save:(NSError**)error;
现在,当使用双指针时,您需要在编程中采取防御措施。首先,您必须确保error
is not的值nil
,然后*error
是 is nil
。您必须这样做,因为您不知道如何对现有对象进行明智的内存管理。例如:
NSError *error = nil;
[self save:&error];
会是正确的。但
NSError *error = [[NSError alloc] init];
[self save:&error];
是一个问题,因为您的save:
方法不会 if error
is retained
or 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
读作“错误地址”。