我們在寫一個方法時,如果希望在方法執行出錯時,獲取一個NSError對象,我們通常會像下面這樣來定義我們的方法
+ (NSString )checkStringLength:(NSString *)str error:(NSError **)error { if (str.length <= 0) { *error = [NSError errorWithDomain:@"ErrorDomain" code:-1 userInfo:nil]; return nil; } return str; }
這段代碼看著沒啥問題,至少在語法上是OK的,所以在編譯時,編譯器並不會報任何警告。
如果我們用以下方式去調用的話,也是一切正常的:
NSError *error = nil; [Test checkStringLength:@"" error:&error];
不過我們如果就靜態分析器來分析一下,發現會在”*error = …“這行代碼處報如下的警告:
Potential null dereference. According to coding standards in ‘Creating and Returning NSError Objects’ the parameter may be null
這句話告訴我們的是這裡可能存在空引用。實際上,如果我們像下面這樣調用方法的話,程序是會崩潰的:
[Test checkStringLength:@"" error:NULL];
因為此時在方法中,error實際上是NULL,*error這貨啥也不是,對它賦值肯定就出錯了。
這裡正確的姿式是在使用error之前,先判斷它是否為NULL,完整的代碼如下:
+ (NSString )checkStringLength:(NSString *)str error:(NSError **)error { if (str.length <= 0) { if (error != NULL) { *error = [NSError errorWithDomain:@"ErrorDomain" code:-1 userInfo:nil]; } return nil; } return str; }
實際上,對此這種方式的傳值,我們始終需要去做非空判斷。