2014-07-20 73 views
0

它是在編寫Objective-c方法時添加錯誤輸出參數的常見模式。
據我知道這是你如何創建,如果事情是錯誤的返回錯誤的方法: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]; 
} 

所以我想好了,我就傳遞錯誤參數裏面的方法,就像這樣:

- (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

您正在傳遞的錯誤地址不是實際的錯誤,這意味着&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); 

您必須通過&錯誤

4

有幾件事情是錯誤的。首先不應該使用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()