2016-02-22 6 views
13

Apple seems to claim SwiftのOptionalタイプはObjective-Cのnilより安全ですが、なぜこのようになっているのかわかりません。Swiftの「オプション」をObjective-Cの「nil」よりも安全にするには?

Optionalnilより安全にする実装の著しい違いは何ですか?これが自分のコードにどのように影響しますか?

+9

スウィフトはオプションの外ではnilをサポートしません。 Optionalはnilを含むことができますが、Non-Optionalはnilを含むことはできません。 "!"を使用して暗黙的にアンラップされた変数を宣言した場合、その変数を使用するときに変数にnilが含まれていると、例外が発生します。したがって、あなたがそれを期待していないときには、nilを含む "魔法のような"変数を扱う必要はありません。 – Michael

+0

@Michaelあなたのコメントは答えとして機能します。 –

答えて

3

私は問題を避けるために変数を使用する前に、変数がnilかどうかを常にチェックします。しかし、驚いたことに、値がnilになることがありますが、たまに何度も起こります。

私はSwiftでますます多くのコードを書いてから、オプションの変数を使用すると実際にnilの値のチェックを無視しないように便利であることがわかりました。私は実際にはnilの変数アクセスによるクラッシュを思い出しません(何かの変数のアンラップを強制しない限り、あなたが何をしているのかわからない限りアンラップしないでください)。

以外にも、私は多くの場所でこのようなコードの多くを書くために使用:

if (obj != nil) { 
    obj.property = ... 
} 

は今、私は単に

obj?.property = ... 

コードは今クリーンでシャープに見えるようにそれを行うことができます。それも好きではないですか?

+0

obj.property = ...はObjective-Cでうまく動作し、何もしないので、これはかなり悪い例です。 – gnasher729

+0

私はObjective-Cについて言及していません。ほとんどのプログラミング言語の一般的なケースです。例えば、Luaでこれを試してみてください。クラッシュ! –

+0

この質問は変更されました。私がこの質問に答えたとき、私はObjective-Cのnilについて言及しなかったと思うし、SwiftとObjective-Cを比較すると思う。この質問はマージまたは変更する必要があります。それは元の意図を失ってしまった。 –

-2

Objective-Cでは、値なしで変数を定義できます。値を割り当てる前にその変数を使用する場合は、未定義の動作が発生します(非常に悪い)。これとは対照的に、スウィフトは、オブジェクトの値が不明なシナリオを防止します。

+1

ARCは数年前に導入されて以来、Objective-Cオブジェクトへのポインタは自動的にnilに初期化されます。未定義の動作はありません。合理的なコンパイル設定を有効にすると、初期化されていない変数を使用しようとするとコードがコンパイルされません。 – gnasher729

2

プログラマがより明示的なコードを書き込まなければならないため、「安全」になります。

  • if let ...guard構文は、明示的に「これらの変数の値がある場合にのみ、これを行う」と言います。
  • プログラマがnilであると予想しなかったときに変数がnilである場合、!シンタックスがプログラムをクラッシュさせます。対照的に

nilノーオペレーションに呼び出しを行うの客観-Cの方法は、プログラムがnilが許容できないようなポイントまで実行を継続させてもよいです。一般的な例の1つはnilNSStringです。多くのAPI呼び出しは、nilNSStringパラメータを受け入れずにアプリケーションをクラッシュした場合を除き、NSAttributedStringを構築する場合を除き、nilNSStringを使用しています。したがって、NSString変数が予期せずnilになると、nil値の属性付き文字列を作成しようとするため、アプリがクラッシュするまでにしばらく時間がかかることがあります。

Optionalalsが解決しようとした問題のより完全な説明については、this post back from 2010 by Daniel Jalkutを検討してください。これはスイフトのずっと前に書かれたものです。

2

一般に、プログラミングでは値を持たない変数(nullまたはnil)を使用しないようにします。そのため、定義されていない動作(例外、エラー、クラッシュ)が発生することが多いからです。

たとえば、参照をnilの代わりに空の配列に設定するのが一般的です。空の配列では、すべてのArrayメソッドを使用できます。 indexOfまたはcountnilでこれらを使用すると、クラッシュする可能性があります。

一部の変数が空でないことを指定できるため、安全に使用でき、コンパイラはnilが割り当てられていないことをチェックします。またコンパイラは、オプションから非オプションへのすべての変換が明示的であることを強制します(必要に応じて常にnilをチェックしています)。

だから、答えはoptionalsことを次のようになります。

  1. が良いプログラミングプラクティスを適用します。
  2. このようなプログラミングエラーを防止し、コンパイル時に

をチェックし、より良いコードを許可します。

可能な場合は常にオプションを避けるようにしてください。オプションの最大の力は、ほとんどの変数がオプションではないという事実です。

+0

あなたは最後の声明を詳しく述べることができますか? "最も有力な選択肢は、ほとんどの変数がオプションではないという事実です。" –

+0

@JoeHuangそれはかなり簡単です。すべての変数がオプションである場合、あなたは選択肢なしで世界に戻ってきます。すべてが「無」になることができます。オプションの能力は 'nil'を特定のライブラリに制限することです。 – Sulthan

+0

私は、非同期プログラミングを検討する際にはより多くの選択肢があると思います。私はほとんどの変数をオプションにする方法を得ていない。 –

関連する問題