web-dev-qa-db-ja.com

ポインタにnullability型指定子がありません

Xcode 7 GMでは、次の警告が表示され始めました。

ポインターにnullability型指定子(_Nonnull、_Nullable、または_Null_unspecified)がありません

次の関数宣言(NSUserDefaults拡張)

- (void)setObject:(nullable id)value
           forKey:(NSString *)defaultName
    objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

この警告が表示される理由と修正方法

59
kelin

ハンドラー/ブロックにもnullableを指定する必要があります

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

どうして?スウィフトが原因です。 Swiftでは、Objective-Cではサポートされていないオプションのパラメーター(?)を使用できます。これは、Swiftコンパイラーがこれらのパラメーターがオプションであることを認識するために、両者のブリッジとして行われます。 「Nonnull」は、Swiftコンパイラーに引数が必要であることを伝えます。オプションであるヌル値可能

詳細については、以下を参照してください: https://developer.Apple.com/Swift/blog/?id=25

55
Ares

Objective Cヘッダーの宣言ブロック(関数と変数)の周りで次のマクロを使用できます。

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END

次に、そのブロック内でnilになる可能性のある参照に対して、null可能注釈を追加する必要があります。これは、関数パラメーターと変数宣言の両方に適用されます。

次のように:

@interface SMLBaseUserDetailsVC : UIViewController < UICollectionViewDelegate>
NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, readonly) IBOutlet UIScrollView *detailsScrollView;
@property (nonatomic, readonly) IBOutlet UICollectionView *photoCV;
@property (nonatomic, weak, readonly) SMLUser *user;
- (IBAction)flagUser:(id)sender;
- (IBAction)closeAction:(nullable id)sender;
- (void) prefetchPhotos;

NS_ASSUME_NONNULL_END

@end

編集*その理由???これは、objective-cクラスをSwiftと相互運用可能にするために、コンパイラがプロパティをSwiftオプションとして処理するかどうかを認識できるように、null可能性を宣言する必要があるためです。 Nullable Objective CプロパティはSwiftではオプションとして知られ、これらのマクロをプロパティのNullable宣言子と組み合わせて使用​​すると、コンパイラはそれらをオプションとして扱うことができます(オプションはモナド-オブジェクトをラップするオブジェクトまたはなし)。

54
Kevin

コンパイラーによって受け入れられた、正しく機能するメソッド宣言:

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))remainHandler;
14
kelin

この回答を投稿して、なぜ_Nonnullまたはnullableを追加する必要があるかを伝えます。

このブログによると: https://developer.Apple.com/Swift/blog/?id=25

Swiftのすばらしい点の1つは、Objective-Cで記述された既存のフレームワークとアプリのコードの両方であるObjective-Cコードと透過的に相互運用できることです。ただし、Swiftには、オプションの参照とオプションではない参照が明確に区別されています。 NSView vs. NSView?。Objective-Cはこれら2つのタイプの両方をNSView *として表します。 Swiftコンパイラーは、特定のNSView *がオプションであるかどうかを確認できないため、タイプは暗黙的にラップされていないオプションNSView!としてSwiftに取り込まれます。

Swiftのすべてです。

9
fishtrees

プロジェクト全体でこの警告を無効にするには

  1. ビルド設定に移動

  2. 「基本」または「カスタマイズ」ではなく、「すべて」タブを表示していることを確認してください

  3. フィールドOther Warning Flagsを検索します

  4. 次のフラグを追加します:-Wno-nullability-completeness

  5. クリーンアップしてビルドします(cmd + shift + k、次にcmd + r)

    -、ビルドが完了した後でも警告が消えるまで数秒かかる場合があります。xCodeが完全に更新されるまで約15秒かかります

3
Albert Renshaw