3

Swift の下の Cocoa フレームワークのNSMetadataItemクラスには、次の関数が含まれています。

func valueForAttribute(key: String!) -> AnyObject!

強制的なアンラップとオプションのチェーンの違い (および詳細) をまだ学んでいます。上記の関数では、これは次のことを意味しますか?

  1. keyパラメータには値が必要です。

  2. 戻り値は値を持つことが保証されていますか?

私の主な関心事は、戻り値に続く感嘆符です-戻り値を割り当てたら:

var isDownloadedVal = item.valueForAttribute(NSMetadataUbiquitousItemIsDownloadedKey)

ブロックを検査するときにブロックを含める必要がありif letますか?それとも、安全に検査できる値を持つことが保証されていますか?

4

2 に答える 2

19

TLDR:Foo!であるかのように扱いFooます。

多くの Cocoa 呼び出しには暗黙的にアンラップされたオプションが含まれており、その必要性がこの機能が存在する理由である可能性が非常に高いです。こう考えるとおすすめです。

まず、 を含まない、より単純なケースについて考えてみましょうAnyObjectUIDevice良い例だと思います。

class func currentDevice() -> UIDevice!

何が起きてる?まあ、常にありcurrentDeviceます。これが返された場合nilは、システムに何らかの深刻なエラーがあることを示しています。したがって、このインターフェースを Swift で構築していた場合、これは返されて処理UIDeviceが完了する可能性があります。しかし、 を返す Objective-C にブリッジする必要がありますUIDevice*。これは決してnilであってはなりませんが、構文的には になる可能性がありますnil。現在、ObjC では、通常、その事実を無視し、ここではチェックしませんnil(特に、nilメッセージングは​​通常安全であるため)。

では、この状況を Swift でどのように表現するのでしょうか? 技術的には であり、最終的には次のようOptional<UIDevice>になります。

class func currentDevice() -> UIDevice?

そして、それを使用するたびに(理想的にはif letブロックで)明示的にアンラップする必要があります。それはすぐにあなたを狂気に駆り立てます。currentDevice()常に値を返します。これOptionalは、ObjC へのブリッジングのアーティファクトです。

そこで、彼らはそれを回避するためのハックを発明しました (これは本当にハックだと思います。ObjC が混ざっていなければ、この機能を構築することは想像できません)。そのハックは、はい、それはですが、そうでOptionalはないふりをすることができ、常に値になることを約束します。

そして、それは!です。この種のものについては、基本的に を無視し、!それがあなたに戻ってきたふりをしてUIDeviceロールアローンします。彼らがあなたに嘘をついて戻ってきたらnil、まあ、それはクラッシュするでしょう. 彼らはあなたに嘘をつくべきではありませんでした。

これはルールを示唆しています:!本当に必要でない限り使用しないでください (そして、ほとんどの場合、ObjC にブリッジする場合にのみ使用する必要があります)。

あなたの特定の例では、これは両方向に機能します:

func valueForAttribute(key: String!) -> AnyObject!

技術的には が必要ですが、それは にOptional<String>ブリッジされているからNSString*です。ここ以外を通過する必要nilがあります。そして、技術的には you を返しますがOptional<AnyObject>、それは にブリッジされているためidです。そうではないことを約束しますnil

于 2014-06-05T13:21:25.317 に答える