2016-03-29 28 views
0

最近XcodeでCLANG_WARN_NULLABLE_TO_NONNULL_CONVERSIONを有効にしましたが、私はObjective-Cコードのnull許容度に関する警告に圧倒されています。最も一般的な警告タイプの1つはImplicit conversion from nullable pointer 'TypeA * _Nullable' to non-nullable pointer type 'TypeA * _Nonnull'です。Clang nullabilityの警告とそのアプローチ

ここで説明した方法で同じタイプのローカルを作成して、これらの警告で削除しようとしました。 https://www.mail-archive.com/xcode-users%40lists.apple.com/msg02260.html この記事では、最初にローカルを使用することで、そのオブジェクトは属性が不特定のnullableであるため、非ナルを期待するメソッドの正当なパラメータとして使用できます。

しかし、私はこれが動き出していると感じていて、本当に有益な方法で問題を解決していません。

誰もこの練習をすでに行っていますか?あなたが取った戦略を分かち合うことができれば幸いです。

+0

どのような問題を解決しようとしていますか?オブジェクトがゼロでないことを知ったときに警告を抑制する?またはオブジェクトがゼロでないことを確認する実際のプロセスですか? – dan

+0

@dan次のようなコードがあるとします。NSMutableData * someData = [NSMutableData dataWithCapacity:d1000]; [someData appendData:[NSString stringWithFormat:@ "$%d"、1000000]]; '。 'appendData:'は非NULLを予期しているので、まずコールの前にNSString *を作成しておいてください。理想的には、私は問題を回避しようとしているコードの余分な行を追加して、まったく何のメリットも与えないので、これをやりたいとは思わない。 – KBancho

+0

警告はもう存在しないという利点があります。追加コード行の価値があるかどうかは、あなた次第です。私はそれに問題は見られません。 – dan

答えて

1

実際、私はその話題を少し混乱させました。私は、ある程度大きなプロジェクトでは、NULL可能性の状況を改善したいと考えました(より迅速に)。ここに私が見つけたものがあります。

まず、あなたがCLANG_WARN_NULLABLE_TO_NONNULL_CONVERSIONをオンにする必要があります(-Wnullable-to-nonnull-conversion

第二に、およそ

最初にローカルを使用して、そのオブジェクトは、属性指定されていないNULL可能、 のように、それはへの合法的なパラメータとして使用することができています非nullを予期するメソッド

これは悪臭を覚え、NONNUL_CAST()というマクロを作成しました。ここではそれを実装する方法の例です:

ここ
#define NONNUL_CAST(__var) ({ NSCAssert(__var, @"Variable is nil");\ 
    (__typeof(*(__var))* _Nonnull)__var; }) 

あなたがハック__typeof(*(__var))* _Nonnull)__varを見ることができますが、それはそれほど悪くないです。 __varのタイプがA* _Nullableの場合は、__varを逆参照しますので、今度はタイプをAとし、再度参照してから_Nonnullとしてください。__varは答えになります。もちろん、何かがうまくいかない場合に備えて、我々は主張する。

は第三に、あなたはすべてのローカル変数にnullabiltyを指定する必要があり、そしてあなたは、このように、NS_ASSUME_NONNULL_BEGIN/ENDにすべてのコードを配置する必要があります

NS_ASSUME_NONNULL_BEGIN 
<your_code_goes_here> 
NS_ASSUME_NONNULL_END` 

あなたが入れそこにあなたのコードの(輸入を除く)EVERY LINE.h.mファイルです。これは、メソッド、戻り値の型、およびプロパティのすべての引数がNULLでないことを前提としています。ヌル可能にしたい場合は、ヌル可能にしてください。

これですべて完了しました。ここ は、典型的な使い方の例である:

- (Atype*)makeAtypeWithBtype:(nullable BType*)btype { 
    Atype* _Nullable a = [btype makeAtype]; 
    if (a) { 
    // All good here. 
    return NONNUL_CAST(a); 
    } else { 
    // a appeared as nil. Some fallback is needed. 
    [self reportError]; 
    return [AtypeFactory makeDeafult]; 
    } 
} 

は今、あなたは、より堅牢なNULL可能な状況があります。それはきれいに見えないかもしれませんが、それは客観的なものなので、不平を言うことはありません。

+0

すばらしい答え!私はこの同じ問題を抱えていました。逆参照と再参照を完全に忘れていました。 –

0

すべての警告が意味をなさないわけではありません。時にはコンパイラの欠点です。たとえば、このコードでは警告は必要ありません。

- (nullable id)transformedValue:(nullable id)value { 
    id result = value != nil ? UIImageJPEGRepresentation(value, 1.0) : nil; 
    return result; 
} 

nullであるかどうかを確認しています。何ができるの?なぜ余分なポインタを作成するのですか?

- (nullable id)transformedValue:(nullable id)value { 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion" 
    id result = value != nil ? UIImageJPEGRepresentation(value, 1.0) : nil; 
#pragma clang diagnostic pop 
    return result; 
} 

なぜこれが正しい答えです:

そこで、我々はこれを行いますか?

まず、コンパイラよりもスマートにすることができます。偽の警告のために、あなたのコードを破棄したくないです。

このソリューションは、抑制する警告メッセージを正確に指定し、1行だけ抑制します。

関連する問題