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

Posted

技术标签:

【中文标题】Objective-c将错误参数传递给内部方法【英文标题】:Objective-c passing error parameter to inside method 【发布时间】:2014-07-20 12:34:32 【问题描述】:

在编写 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 *'

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

【问题讨论】:

【参考方案1】:

有几件事是错误的。首先,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]NSLog()

【讨论】:

【参考方案2】:

您传递的错误地址不是实际错误,这意味着&error 所以你需要取消对错误指针的引用。NSError *__autoreleasing *你将参数作为error的地址。我们通常这样做是因为objective c只能返回一个值。但是需要从我们调用方法的地方知道错误因此,如果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);

你必须通过 &error

【讨论】:

以上是关于Objective-c将错误参数传递给内部方法的主要内容,如果未能解决你的问题,请参考以下文章

将 func 作为 Linq 中的参数传递给实体和“内部 .NET Framework 数据提供程序错误 1025”错误

如何将 NSData 参数传递给在 swift 3 中调用的目标 c 方法?

将参数传递给 Rake 任务中的方法 [重复]

将经过默认参数提升的对象传递给“va_start”

调用如何将其参数传递给内部函数? [复制]

将对象作为参数传递给函数