Ios Objective-c将错误参数传递到内部方法

Ios Objective-c将错误参数传递到内部方法,ios,objective-c,nserror,Ios,Objective C,Nserror,在编写Objective-c方法时,添加错误输出参数是一种常见的模式。 据我所知,这就是如何创建一个方法,在出现错误时返回错误: - (void)doSomethingWithObj:(id)obj error:(NSError *__autoreleasing *)error { BOOL success = NO; // do somthing... if (!success) { *error = [NSError errorWithDomain

在编写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错误检查也会返回YES。 2.日志行生成此警告:格式指定类型“id”,但参数的类型为“NSError*\uuu autoreleasing*”


那么我在这里做错了什么呢?

您传递的是错误地址,而不是实际错误,这意味着&error 因此,您需要取消错误指针的引用。NSError*\uu autoreleasing*您将参数作为错误地址。我们通常这样做,因为目标c只能返回一个值。但是,需要从调用方法的位置知道错误,因此,如果调用函数中出现错误,则将其作为错误地址传递将改变错误。 所以,如果有任何错误出现在下面的行

NSArray *results = [context executeFetchRequest:request error:error];
然后自动知道调用函数,即doSomethingWithObj

使用

而不是

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

您必须通过&error

有几件事出错了。首先,不应使用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;
}  
测试结果为零,而非错误为非零:

其次,error参数通常是可选的,就像在代码中传递nil时看到的那样,nil实际上应该是NULL。因此,您需要在取消引用之前测试它是否已通过,请参阅上面的代码

不过,要回答您的总体问题,是的,最好将错误参数传递给从属方法调用,这是常用的

我不知道你的2。直到你更新你的代码。。。待命。我想你的2。问题是因为您需要将[error localizedDescription]与NSLog一起使用

NSLog(@"error %@", (error).description);
- (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;
}  
- (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");
    }
}