AppleStruct/Classを選択する条件

4906 ワード

***Reference コンテンツ範囲:Appleドキュメント

n/a.結論


まず,安全性の観点から,「できるだけ構造を用いる」と結論した.

値タイプを使用している場合は、他のコードセクションではインスタンスを変更できないため、コードの一部に集中できます.
ただしclassを使用する必要がある場合は
  • Objective-Cでclass定義のタイプを使用する場合、
  • 「DB接続」のようにアプリケーションフルコードで状況を共有する必要がある場合、
  • 継承が必要な場合はprotocol+structの組合せを使用して実現できます。

    classとは異なり、protocolはstruct/class/enumと継承関係があります.

    Overview


    structとclassはデータと設計の動作を格納する良い選択です
    しかし、彼ら二人は似ているので、どちらを選ぶのが難しいことがあります.
    どの選択が正しいかを判断するために、以下の4つの基準を提案します.
    デフォルトではstructを使用します Objective-Cコードに関連付ける必要がある場合はclassを使用します。 データのIDを処理する必要がある場合はclassを使用します(参照) 継承が必要な場合はstruct+プロトコルの組合せを使用します

    各基準の原因を理解してみましょう.

    1.デフォルトでstructを使用


    一般的なタイプのデータを表示する場合はstructを使用します.SWIFTでは、structは他の言語でクラスのみが使用できる複数の特性を使用できます.
    structには、ストレージ構成、計算構成、およびメソッドが含まれます.
    さらに、SWIFTのstructは、プロトコルを使用してデフォルトのインプリメンテーションを指定することもできる.
    SWIFT標準ライブラリとFoundationフレームワークは、頻繁に使用する要素をstructにします.数字、文字列、配列、辞書など
    structを使用すると、アプリケーション全体のステータスを考慮することなく、コードの一部を容易に推定できます.
    structは値タイプだからです.意図的に通知しない限り、appの他の部分ではstructの地域的な変化は見られない.(気にする必要はない)
    したがって、他のコードセクションではインスタンスを変更できないため、コードの一部に集中できます.
    参照タイプのclassを使用すると、システムが大きく複雑である場合は、相互参照可能であり、インスタンスを随所に変更できるため、コード全体に注意する必要があります.

    2.Objective-Cコードに関連付ける必要がある場合はclassを使用します。


    Objective-C APIを使用してデータを処理する必要がある場合、またはObjective-C Frameworkで「class」と定義されているタイプを使用してデータモデリングを行う必要がある場合は、classとclassを使用して継承します.
    たとえば、多くのObjective-C Frameworkはそのサブクラス(?)です.彼らに暴露させる

    3.データのIDを処理する必要がある場合はclassを使用します(参照)


    SWIFTのclassは参照タイプなので、自動的にidentity(?)を読み込みます.だから来ました.
    これは、2つの異なるclassインスタンスに格納されているpropertyの値が同じであっても、identity演算子(===)によって異なりますか?疑われる
    これは、アプリケーション間でclass instanceを共有する場合、インスタンスを変更すると、そのコードを参照する他のすべての部分に変更が表示されることを意味します.
    インスタンスにこのようなidentityを持たせる場合はclassを使用します.
    たとえば、ファイルハンドル、ネットワーク接続、共有ハードウェアブローカなどです.
    たとえば、ローカル・データベース接続を表すタイプがある場合は、データベース・アクセスを管理するコードがデータベースのステータスを完全に制御する必要があります.
    この場合はclassを使用したほうがいいです.ただし、アプリケーションのどの部分が共有データベースにアクセスできるかを制限する必要があります.
    Important 同一性に注意しなければならない。appコミュニティでclass instanceを共有すると、論理エラーが発生しやすい。 このように多くの共有インスタンスでは、変更の結果を予測できない場合があります。したがって、これらのコードを正しく記述する必要があります。

    identityを制御する必要がない場合はstructを使用します。


    モデリング中のデータがエンティティに関する情報であり、エンティティに識別が含まれているが制御を必要としない場合はstructを使用します.
    Entity:保存および管理が必要なデータのセット-Zedd
    たとえば、リモート・データベースを参照するアプリケーションでは、インスタンスの識別は完全に外部エンティティによって所有されてもよいし、識別子によって伝達されてもよい.
    (identityの場合、appは決定権がなく、外部の規定に従って使用するだけです)
    アプリケーションのモデル整合性が外部サーバに格納されている場合は、レコードを識別を含む構造にモデリングできます.
    次の例では、サーバから受信したjsonResponseは、符号化されたPenPalRecordを含む.
    struct PenPalRecord {
        let myID: Int
        var myNickname: String
        var recommendedPenPalID: Int
    }
    
    var myRecord = try JSONDecoder().decode(PenPalRecord.self, from: jsonResponse)
    PenPalRecordのようなタイプをシミュレートするには、ローカル変更を行うと便利です.
    たとえば、appはフィードバックに基づいて複数の異なるpenpalsを推奨する場合があります.PenPalRecord structは元のデータベースの識別を制御しないため
    localとして宣言されたPenPalRecordに変更を加えてもDBには影響しません
    appの他のセクションでmyNicknameを変更してサーバにコミットすると、ニックネームの変更によってサーバによって拒否される可能性があります.ただし、それでも、識別を誤って選択した場合に要求を出すことはありません.identity(myID)は定数として定義されているため、ローカル変更は許可されません.
    したがって、データベース要求が他のレコードを意外に変更することはありません.

    4.継承が必要な場合はstruct+プロトコルの組合せを使用します。


    structもclassも継承の形式をサポートしています(うん?)
    structとprotocolはプロトコル採用動作のみを実行し、クラスを継承できません.
    (プロトコル継承はプロトコル採用を示すようです)
    ただし、classのようにプロトコル継承+structの組み合わせを使用して継承レイヤを作成できます.
    最初から継承関係を作成する場合は、プロトコル継承が好きです.
    プロトコルはclass、struct、enumが継承に参加することを許可します.
    逆にclass継承はclass間でのみ行われます
    データのモデリング方法を選択している場合は、プロトコル継承を書き込み、structに適用します.