2011-01-17 7 views
5

私はこの方法を扱う私のエラーをコーディングするのが習慣になった:NSError:エラーを検出するためにnilを使用すると、実際にエラー報告がオフになりますか?

NSError* error = nil; 
NSDictionary *attribs = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:&error]; 
if (error != nil) { 
    DLogErr(@"Unable to remove file: error %@, %@", error, [error userInfo]); 
    return; 
} 

しかし、私はこの間違ったを得たように思えドキュメントを見て:

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error 

If an error occurs, upon return contains an NSError object that describes the problem. Pass NULL if you do not want error information.

技術的にはありませんがあるがnilとNULLとの違いは、実際にはこれを無効にしていることを意味します(上記の例の削除が失敗したとしてもエラーメッセージは表示されません)。 これをコードする良い方法はありますか?

ありがとうございました。

+1

nil'と 'NULL'、および' 'Nil'に差があります。 'nil'はインスタンスオブジェクト、' Nil'はクラスオブジェクト、 'NULL'は他のものです。 '&error'はメモリアドレスでオブジェクトではないので' NULL'を使用してください – Philip007

答えて

13

まず第一に、次の行は本当に意味がありません。

私はあなたがNULLの値で不思議に思っているものを見ると思います。メソッドシグネチャのerrorパラメータに2 *がどのようにあるのか注意深く注意してください。

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error 

つまり、ポインタへのポインタを意味します。 &errorを渡すと、NSErrorへのポインタのアドレスが渡されます。(私の頭がまだポインタへのポインタを扱うときに泳ぐために、他の人がおそらく私を助けてくれるかもしれません。つまり、errornilに設定しても、errorはこのメソッドに渡されません。これは&errorに渡しています。

だから、ここでは再記述された方法がどのように見えるかです:

// If you want error detection: 
NSError *error = nil; 
if (![[NSFileManager defaultManager] removeItemAtPath:fullPath 
      error:&error]) { 
    NSLog(@"failed to remove item at path; error == %@", error); 
    // no need to log userInfo separately 
    return; 
} 

// If you don't: 
if (![[NSFileManager defaultManager] removeItemAtPath:fullPath 
      error:NULL]) { 
    NSLog(@"failed to remove item at path"); 
    return; 
} 
+0

BOOLを返すメソッドについてうまくキャッチ!私はそれを完全に逃した。 –

0

いいえ私は同じ方法で行い、エラーを検出するためにはうまく動作します。 NULLを渡すのではなく、NULLにポインタを渡しています。これは非常に異なることです。あなたが追加したいかもしれない別のオプションがあります。 NULLを渡す

if (error != nil){... 
}else{ 
    [NSApp presentError:error] 
} 
9

は、以下を意味する:

BOOL itemRemoved = [[NSFileManager defaultManager] removeItemAtPath:fullPath 
    error:NULL]; 

即ち、errorパラメータがNULLあります。内部的には、有効なポインタが渡された場合は-removeItemAtPath:error:が表示されます。 NULLの場合、単にエラーをNSErrorインスタンスとして報告しませんが、戻り値はメソッドが正常に完了したかどうかを示します。

また、テストが間違っています。メソッドが正常に完了したとしても、に設定される可能性があるため、エラーが発生したかどうかを検出するには、出力パラメータerrorを使用しないでください。その代わりに、メソッドの戻り値を使用してエラーを検出する必要があります。 (この特定の場合に)戻り値がNOある場合、エラーに関する情報を取得するためにerror出力パラメータを使用します。Error Handling Programming Guide

Important: Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.


編集を引用

NSError *error = nil; 
BOOL itemRemoved = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:&error]; 
if (itemRemoved == NO) { 
    DLogErr(@"Unable to remove file: error %@, %@", error, [error userInfo]); 
    return; 
} 

:NSGodが指摘したように、-removeItemAtPath:error:BOOLであり、NSDictionary *ではありません。私はそれを反映するために私の答えを編集しました。

NSDictionary *attribs = [[NSFileManager defaultManager] 
removeItemAtPath:fullPath error:&error]; 

-removeItemAtPath:error:がBOOL値ではなく、辞書を返します。

+0

+1素晴らしい正確さのため –

+0

すばらしい説明ありがとうございます。通話中の検出コードがどのように見えるか簡単な例がありますか? nilとnilへのポインタを区別することが可能であるという(NSError **)エラー宣言によるものですか? – EtienneSky

+0

@EtienneSky私の答えは、戻り値を調べることによってエラーが発生したかどうかを検出する方法を示しています。 NSGodの答えでも、戻り値を格納するために変数を使用することはありません。そして、そうです、 'NSError **'は 'nil'オブジェクト(' NSError * ')と' NSError * 'オブジェクトへのポインタ(' NSError ** ')を区別することを可能にします。出力パラメータにオブジェクトを格納する必要がないことを示すためには 'NULL'を返します。 –