3

nullability に関する Apple のブログでは、次のように言及されています。

「... Swift では、オプションの参照と非オプションの参照の間に強い区別があります。たとえば、NSView と NSView? のように、Objective-C はこれら 2 つのタイプの両方を NSView * として表します。Swift コンパイラは、特定の NSView * がオプションであるかどうかに関係なく、型は暗黙的にアンラップされたオプションの NSView として Swift に取り込まれます!"

これは、Objective-C メソッドが Swift で暗黙的にラップされていないオプションを返すと宣言したときに、実際にクラッシュする可能性があることを意味しますか (暗黙的にラップされていないオプションで宣言されたメソッドの一部が nil を返す可能性があるため)。それとも、Apple は絶対に nil を返さない Objective-C メソッドだけが、暗黙的にラップ解除されたオプションとして宣言されるようにしますか?

4

2 に答える 2

6

Apple のフレームワークは特別なものではありません。当初、 Swift で Objective-C から使用したすべて(すべてのオブジェクト) は、暗黙的にアンラップされたオプションでした。これは、Objective-C のすべてのポインターが を返す可能性があるためnilです。

実際、Objective-C の null 可能性アノテーションの時代でさえ、 とアノテーションが付けられたメソッドnonnullが を返す可能性があることは完全に不可能というわけではありませんnil。Objective-C は nullability ルールを強制しません。Swift から安全に使用できるように、コードに注釈を付ける手段を提供するだけです。Apple のフレームワークの場合、この問題が発生しないことはかなり安全な賭けだと思います。または、そうする場合は、Xcode の次のバージョンで修正されます。

しかし繰り返しになりますが、Objective-C のライブラリとフレームワークに由来する、暗黙的にアンラップされたオプションについて特別なことは何もありません。暗黙的にアンラップされたオプションがあなたに伝える唯一のことは、フレームワークの作成者がまだライブラリに注釈を付ける努力をしていないということです (暗黙的にアンラップされたオプションを注釈付きライブラリに残すことはできません)。 はい、これらの暗黙的にアンラップされたオプションはnil、アプリケーションをクラッシュさせる可能性があります。

Apple の場合、何らかの理由で異なるプロジェクトで Xcode 7 と Xcode 6 を使用している場合、Xcode 7 の更新注釈が非オプションとして宣言したものを使用する場合、Xcode で暗黙的にアンラップされたオプション バージョンを想定します。 6はnilうまくいかないかもしれません。しかし、Xcode 7 でオプションになっているものを使用する場合、Xcode 6 からの暗黙的にアンラップされたバージョンがnilおそらくアプリをクラッシュさせる可能性が低いと仮定すると、.

最終的に、Swift では、暗黙的にアンラップされたオプショナルの使用はほとんどありません。暗黙的にアンラップされたオプションの主な用途は、クラスの初期化が戻る前に設定できないクラス プロパティ用に予約する必要があります (たとえば、@IBOutletsビュー コントローラー)。そうしないと、スタック オーバーフローに関する多数の「予期せず見つかった nil」の質問の原因になりがちです。


「オプションではなく、暗黙的にアンラップされたオプションを返すのはなぜですか?」という質問に対して、いくつかのポイント...

まず、これは言語設計の問題です。私は Objective-C や Swift の言語設計チームに所属していません。これらのチームの誰かが立ち寄ってその質問に答えてくれる可能性は低いです...

2 つ目は、言語が相互運用できるように設計されていることです。nullability アノテーションが追加されていない Objective-C ファイルは、すべてが Swift で暗黙的にアンラップされたオプションであるかのように扱われます。

第 3 に、暗黙のオプションの理由はif let、変数が実際にnon-nil. この理由のほとんどは、おそらく、これらのメソッドのほとんどが実際には返されないと考えているためですnil

第 4 に、可能性があるものと可能性がないものがわかっている場合はnil、実際に先に進み、Objective-C コードにどのようにアノテーションが付けられるかについて両方の仮定を処理する方法で Swift コードを書くことができます。

たとえば、暗黙的にアンラップされたオプションを使用すると、もちろん、それを非オプションのように扱い、アンラップに伴うマイナーな冗長性の一部を取り除くことができます。

さらに、暗黙的にラップ解除されたオプションを使用すると、それが である可能性があると思われる場合でも、nilオプションのラップ解除のものはすべてそれで動作します。

例:

override func someFunc(implicitVal: String!) -> String {
    return implicitVal ?? "It was nil!"
}

override func someOtherFunc(implicitVal: String!) -> String {
    return implicitVal
}

それらをすべてオプションとして想定した場合、2 番目の例は機能しません。

それらをオプションではないものと仮定すると、最初の例は機能しません。

暗黙的にアンラップされたオプションにより、値が である可能性について正しい仮定を行う場合、Swift 開発者はオプションを自由に扱うことができますnil

于 2015-06-17T12:22:19.070 に答える
1

これは、Objective-C メソッドが Swift で暗黙的にラップされていないオプションを返すと宣言したときに、実際にクラッシュする可能性があることを意味しますか (暗黙的にラップされていないオプションで宣言されたメソッドの一部が nil を返す可能性があるため)。

いいえ。暗黙的にアンラップされたオプションはオプションです。つまりnil、完全に受け入れられる値です。暗黙的にアンラップされたオプショナル asnilはクラッシュしませんが、オプショナル バインディングまたはオプショナル チェーンなしでメンバーに直接アクセスしようとした場合にのみ、クラッシュします。

それとも Apple は、絶対に nil を返さない Objective-C メソッドだけが、暗黙的にラップ解除されたオプションとして宣言されるようにしますか?

を返さないことがわかっている場合、Apple は、監査後に、暗黙的にアンラップされたオプションではなくnil、非オプションとして宣言します。返される可能性があるかどうかが不明な場合にのみ、暗黙的にラップ解除されたオプションを返します。nil

于 2015-06-17T21:49:29.930 に答える