2011-01-17 17 views
5

Hatayı kodlama alışkanlığımı bu şekilde ele aldım:NSError: Hata saptamak için nil kullanmak hata raporlamasını gerçekten kapatıyor mu?

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

Ama belgelere bakmak Yanlış yazıyormuş gibi görünüyor:

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

Bir hata oluşursa, dönüş, sorunu açıklayan bir NSError nesnesini içerir. Hata bilgisi istemiyorsanız NULL geçirin.

Teknik olarak nil ile NULL arasında bir fark yoktur, bu yüzden bunu gerçekten kapatıyorum ve asla bir hata mesajı almayacağım anlamına gelir (yukarıdaki örnekte silme başarısız olsa bile)? Bunu kodlamanın daha iyi bir yolu var mı?

Teşekkürler.

+1

nil' ve 'NULL' ve' Nil' 'arasındaki fark var IS. 'nil' örneğin nesne, 'Nil' sınıf nesnesi, 'NULL' başka bir şey içindir. 'Hata ', bellek adresi değil, nesne değil, mükemmel doğruluk için – Philip007

cevap

13

Öncelikle, aşağıdaki satırı gerçekten mantıklı değil.

NULL değeriyle merak ettiğiniz şeyleri görüyorum. yöntem imzası hata parametresinde 2 * 'in nasıl orada olsa da, dikkatli bir şekilde edin: bir işaretçi için bir işaretçi anlamına

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

. &error'u ilettiğinizde, işaretçinin adresini NSError'a iletiyorsunuz.(Başkasına işaretçilerle çalışırken başım hala yüzmeye başladığında, başkası buraya muhtemelen yardım edebilir). Başka bir deyişle, error'u nil olarak ayarlamış olsanız bile, error yöntemini iletime geçirmiyorsunuz demektir, &error içinde iletiliyorsunuz.

Yani, burada yeniden yazılı yöntem gibi görünmelidir ne:

// 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'u döndüren yöntemle ilgili güzel bilgiler! Bunu çok özledim. –

0

Hayır Aynı şekilde yapıyorum ve hataları algılamak için gayet iyi çalışıyor. NULL 'u geçmiyorsunuz, NULL' a bir işaretçiyi çok farklı bir şeyden geçiyorsunuz. Eklemek isteyebileceğiniz başka bir seçenek olsa da. NULL geçen

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

aşağıdaki anlama gelir:

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

, error parametresi NULL yani olup. Dahili olarak, geçerli bir işaretçinin geçip geçmediğini -removeItemAtPath:error: görür. NULL ise, yalnızca NSError örneği olarak hatayı bildirmez - döndürme değeri yöntemin başarıyla tamamlanıp tamamlanmadığını gösterir.

Ayrıca, sınamanız yanlış. Yöntem başarıyla başarıyla tamamlansa bile, ayarlanabileceğinden bir hata oluşup oluşmadığını saptamak için error çıkış parametresini kullanmamalısınız. Bunun yerine, hataları algılamak için yöntemin dönüş değerini kullanmalısınız.


Edit,

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

Error Handling Programming Guide aktaran

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.

: (bu özel durumda) Dönüş değeri NO ise, hata hakkında bilgi almak için error çıktı parametresini kullanın : NSGod işaret ettiğinden, -removeItemAtPath:error:, değil BOOL'u döndürür. Cevabımı da yansıtmak için düzenledim.

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

-removeItemAtPath:error: bir BOOL değeri değil, bir sözlük verir:

+0

+1' yi kullanın. –

+0

Büyük Açıklama, Çok teşekkürler. Çağrıdaki tespit kodunun nasıl görünebileceğine dair kısa bir örnek var mı? (NSError **) hata bildirimi nedeniyle bir işaretçi arasında nil ve nil arasında ayrım yapmak mümkün mü? – EtienneSky

+0

@EtienneSky Cevabım, dönüş değerini inceleyerek bir hatanın oluşup oluşmadığını nasıl saptadığını gösterir. NSGod’un cevabı da bunu yapar, ancak dönüş değerini saklamak için bir değişken kullanmadan. Ve evet, “NSError **”, “nil” nesnesini (“NSError *”) ve bir “NSError *” nesnesine (yani, “NSError **') bir işaretçi arasında ayrım yapmanıza olanak tanır, bu geçerli bir işaretçi olabilir. veya "NULL", bir parametrenin çıkış parametresinde saklanmasına gerek olmadığını belirtmek için. –