6

CLANG_ANALYZER_NONNULL(つまり-Xclang nullability)を使用すると、「 null 以外の値を返すことが期待される関数から Null が返されます」という結果が得られました。

ここに画像の説明を入力

Xcode 7.3 および iOS 9.3 のドキュメントを使用して確認initWithFrame:したところ、次のものが返されnilます。

説明

しかし、UIView.h はすべてをNS_ASSUME_NONNULL_BEGINでカプセル化するため、次のように解釈できます。

インターフェース

なので:

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

アップデート

Xcode のドキュメントが更新され、次のようになりました。 initWithFrame: ドキュメント

したがって、これ以上の競合はありません。

4

2 に答える 2

3

UIViewのイニシャライザの場合、スーパー イニシャライザを呼び出した結果を防御的にチェックしないことをお勧めします。これは、失敗した割り当て-initWithFrameから回復するためにアプリケーションが実行できることは実際には何もないためです。UIView

また、Xcode 7.3 ベータ 4 以降、静的アナライザーはここで警告しなくなりました。-init-copy、およびファミリーから nil を返すことについて-mutableCopy、これらのメソッドがnonnull型修飾子を含む戻り値の型を持っている場合でも、警告を表示しないようになりました。

于 2016-02-23T19:51:17.073 に答える
1

多くの場合、ドキュメントが取り残されたり見落とされたりするため、通常はヘッダーが優先されます。UIKit(他のCocoaTouchフレームワークの中でも) ヘッダーは、別の理由でドキュメントよりも最新です:Swift相互運用性が向上します。

したがって、2番目のアプローチを使用する必要があります。

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

この初期化子から戻るnonnullことも論理的です。UIViewは、最終的に画面にレンダリングされる何かに関する情報を保持する抽象オブジェクトであり、それ自体には多くの制限がありません。

同様に、文字列には明確に定義された要件があり、 1 つはそれらを満たさないため、nil 文字列を[NSURL URLWithString:]に渡すことはあまり意味がありません。したがって、ここに注釈を付けるのは理にかなっています。NSURLnilnonnull

于 2016-02-22T18:22:36.707 に答える