Objective-c将错误参数传递给inside方法

时间:2014-07-20 12:34:32

标签: ios objective-c nserror

它是在编写Objective-c方法时添加错误输出参数的常见模式 据我所知,这是如何创建一个方法,如果出错,返回错误:

- (void)doSomethingWithObj:(id)obj error:(NSError *__autoreleasing *)error {
    BOOL success = NO;

    // do somthing...

    if (!success) {
        *error = [NSError errorWithDomain:@"the.domain" code:0 userInfo:nil];
    }
}  

现在有时你只想要这个错误参数来反映你在方法中使用的其他方法中发生的错误,让我们说:

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:nil];
}  

所以我认为好,我只是将error参数传递给inside方法,如下所示:

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:error];
    if (error) {
        NSLog(@"error %@", error);
    }
}  

但这种方法有两个问题:
1.即使没有错误,if (error)支票也会返回YES 2.日志行生成此警告:Format specifies type 'id' but the argument has type 'NSError *__autoreleasing *'

那我在这里做错了什么?

2 个答案:

答案 0 :(得分:5)

有几件事是错的。首先,NSError对象不应该用于测试错误,而是使用方法的返回值。因此,您的第一个示例方法应返回BOOL以表示成功:

- (BOOL)doSomethingWithObj:(id)obj error:(NSError *__autoreleasing *)error {
    BOOL success = NO;

    // do somthing...

    if (!success) {
        if (error) {    // Check it's been passed, and if so create the error object.
            *error = [NSError errorWithDomain:@"the.domain" code:0 userInfo:nil];
        }
    }

    return success;
}  

测试resultsnil,而非error为非nil

- (void)fetchObjectInContext:(NSManagedObjectContext *)context error:(NSError *__autoreleasing *)error {
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SomeObject"];

    NSArray *results = [context executeFetchRequest:request error:error];
    if (!results) {
        if (error && *error)
            NSLog(@"error %@", [(*error) localizedDescription]); // Here is your 2. I think.
        else
            NSLog(@"Unknown error");
    }
}  

其次,error参数通常是可选的(在您传递nil的代码中可以看到,实际应该是NULL。因此,您需要在解除引用之前测试它是否已通过(参见上面的代码)。

但是,要回答您的整体问题,是的,将error参数传递给下级方法调用是很好的,并且是常用的。

我不知道你的2.直到你更新你的代码......待命。我认为你的2.问题是因为你需要[error localizedDescription]使用{{1} }}

答案 1 :(得分:1)

您传递的错误地址不是实际错误,这意味着&error 因此,您需要对错误指针进行解除。NSError *__autoreleasing *您将参数作为error的地址。我们通常这样做是因为objective c只能返回一个值。但是错误需要从我们调用mehod的地方,如果calle function中出现错误,则将其作为错误地址传递将更改为错误。 因此,如果任何错误出现在行

之下
NSArray *results = [context executeFetchRequest:request error:error];

自动知道calle functiondoSomethingWithObj

if (*error) {
    NSLog(@"error %@", (*error).description);
 }

使用

NSLog(@"error %@", (*error).description);

而不是

NSLog(@"error %@", (error).description);

你必须传递&错误