2016-02-21 41 views
4

使用CLANG_ANALYZER_NONNULL(即-Xclang nullability),我得到了「空是從預計將返回一個非空值函數返回」:'[UIView initWithFrame:]'的衝突文檔:可爲空還是非空?

enter image description here

使用的Xcode 7.3和iOS 9.3的文檔,我檢查initWithFrame:它可以返回nil

description

但UIView.h封裝用的一切NS_ASSUME_NONNULL_BEGIN,所以我們可以解釋如下:

interface

爲:

- (nonnull instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER; 

所以文檔解釋了它的nullable,而頭文件說,這是nonnull。哪一個信任?

我應該寫:

- (instancetype)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (!self) { 
     // workaround for clang analyzer 
     return (void * _Nonnull)nil; 
    } 
    // Initialization code 
    return self; 
} 

或者:

- (nonnull instancetype)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    // Initialization code 
    return self; 
} 

UPDATE

Xcode中的文檔進行了更新,現在是: initWithFrame: documentation

所以沒有更多的衝突。

+1

這取決於你的意思是「信任」。編譯器(和相關工具)將「信任」註釋,而不是文檔。如果你希望你的代碼在沒有警告的情況下通過,並且不讓Swift用戶頭疼,那麼假設'nonnull'屬性是正確的。 – Avi

+0

面對'[NSURL URLWithString:]'類似的問題,因爲聲明希望該字符串爲'nonnull',但描述指出它可以是'nil'。 –

回答

2

UIView-initWithFrame初始化的情況下,建議是不是防守檢查調用超級初始化的結果,因爲沒有什麼現實的應用程序可以做從失敗UIView分配恢復。

此外,從Xcode 7.3 beta 4開始,靜態分析器不再警告此處。即使在這些方法返回類型爲nonnull類型限定符時,它現在也不會警告從-init-copy-mutableCopy家庭返回零,以避免警告正確的這種常見防禦性用語。

+0

你好Devin。謝謝你的回答。我不是那個讓你失望的人,因爲我知道你從蘋果公司工作以來[你過去回覆過我](https://llvm.org/bugs/show_bug.cgi?id=26143)。我知道我應該更多地信任Apple的頭文件,所以我將刪除返回'nonnull instancetype'的方法的防禦代碼。 –

+0

這是來自官方消息,還是基於最新XCode beta的靜態分析器行爲? – Cristik

+0

德文,你可以看看http://stackoverflow.com/q/34195149/1033581嗎?或者確認[[AFURLSessionManager(nonnull instancetype)initWithSessionConfiguration:](https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLSessionManager.m#L511)]返回'nil'? –

1

標題通常優先,因爲文檔多次被遺忘或忽略。 UIKit(其他CocoaTouch框架)標題比文檔更新,因爲另一個原因:更好的Swift互操作性。

所以,你應該用第二種方法去:

- (nonnull instancetype)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    // Initialization code 
    return self; 
} 

從這個初始化返回nonnull,也是順理成章的,作爲一個UIView是一個抽象的對象,它包含有關的東西,最終會在屏幕上呈現的信息,它對自己沒有太多的限制。

同樣,也沒有多大意義,一個零字符串傳遞給[NSURL URLWithString:]作爲NSURL串有明確規定的要求,以及nil一個不滿足他們,所以是有意義的這裏有nonnull註解。