問題タブ [protocol-oriented]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ios - プロトコルを使用して Swift で構成可能なオブジェクトを構築する
Swift でコンパス可能なオブジェクトを構築する方法を作成しようとしています。私は自分が持っているものでほとんどそこにいるように感じますが、それでも100%正しいわけではありません.
私が目指しているのは、FlowController
オブジェクトを作成UIViewControllers
して必要な依存関係を与えることができるオブジェクトを持つことです。
私がやりたいことは、この作業をできるだけゆるくすることです。
ここに、機能するが理想的ではない小さな例があります。説明します...
コンポーネントとして使用できる 2 つのオブジェクトを次に示します...Wallet
とUser
.
Component
次に、これらのそれぞれのケースを持つ列挙型を定義します...
requiresComponents
...そして、の配列を返すメソッドを定義するプロトコルComponents
。
ここで問題が発生します。「ファクトリ オブジェクト」がコンポーネントをオブジェクトに入れるためには、プロトコルでもプロパティComposable
を定義する必要がありますuser
。wallet
これらのプロパティを「オプション」(オプションではない) にしようとして、Composable
これらの変数を nil として定義するプロトコルの拡張を定義しました。
次に、作成したいクラスを宣言しますComposable
。ご覧のとおり、User
コンポーネントが必要で、変数を宣言しています。
これで、FlowController
これらが作成され、コンポーネントが追加されます。var
ここで、オブジェクトを取得し、そのローカルバージョンを作成してから、更新されたオブジェクトを返す必要があることがわかります。これは、プロトコルに準拠するオブジェクトのタイプがわからないため、パラメーターを変更できないためだと思います。
ここでオブジェクトを作成します。
ここで、コンポーネントを追加します。本番環境では、これはすべて 内で行われますFlowController
。
ご覧のとおり、ここで機能します。ユーザー オブジェクトが追加されます。
ただし、ご覧のとおり。プロトコルで vars を宣言したので、composable
オブジェクトもwallet
コンポーネントへの参照を持っています (ただし、常に nil になります)。
私はこれで約 95% の道のりを進んでいるように感じますが、私ができるようにしたいのは、プロパティの宣言方法を改善することです。私が望むのは、その最後の行が...composable.wallet
コンパイルエラーになることです。
プロパティの宣言をプロトコルの外に移動することでこれを行うことができますが、プロトコルに準拠するオブジェクトにプロパティを追加できないという問題がありComposable
ます。
ファクトリ オブジェクトが宣言に依存せずにプロパティを追加できることは素晴らしいことです。または、「このオブジェクトにユーザーを呼び出すプロパティがある場合、それにユーザーコンポーネントを追加する」というある種のガードがあります。またはそのようなもの。
この作業の残りの 5% を取得する方法を誰かが知っていれば、それは素晴らしいことです。私が言ったように、これはうまくいきますが、理想的な方法ではありません.
ありがとう
ハッキー編集
うーん... ばかげた、恐ろしい、「誰もこれをすべきではない」編集として。プロトコル拡張を次のように変更しました...
少なくとも、定義していない変数にアクセスしようとすると、プログラムがクラッシュします。しかし、それはまだ理想的ではありません。
ダニエルのブログを読んだ後に編集
OK、やりたいことはできたと思います。それが正確にSwiftyであるかどうかはわかりません。とはいえ、そうかもしれないとも思います。セカンドオピニオンを探しています:)
それで、私のコンポーネントとプロトコルはこのようになりました...
現在、ファクトリメソッドが変更されています...
これにより、私はこれを行うことができます...
ios - Swift プロトコル指向の拡張機能
Swift でのプロトコル指向プログラミングと、拡張機能のしくみと提供できる拡張性のレベルについて理解しようとしています。
Playgrounds で実行した次のコード スニペットを用意します。
私が印刷するものは次のとおりです。
とにかく、すべての拡張機能が実行されることを保証できますか?
理想的には、次の出力を得たいと思います。
私は、Swift が型に関して最も強い一致を選択することを理解しています。実際、ProtocolA が ProtocolB と ProtocolC の両方に一致する実装を提供しないと、コンパイル時エラーが発生します。これを回避できる方法はありますか?
ありがとう。
ios - 汎用プロトコルを含む、プロトコル タイプの異種混合
と の両方をParentProtocol
含む型の 1 つの配列を作成しようとしています。異種配列をループし、 type だけの値を返す関数を作成する方法はありますか? ChildProtocol
Child_With_Value_Protocol
Child_With_Value_Protocol
これには、アーキテクチャの変更が必要になる場合があります。すべてのソリューションに開かれています。
試みられた失敗した解決策 #1
protocol 'Child_With_Value_Protocol' can only be used as a generic constraint because it has Self or associated type requirements
これは、単に に変換されたときにコンパイラが型を認識しないため、理にかなっている のエラーでChild_With_Value_Protocol
失敗します。これは、次の失敗したソリューションにつながります。
試みられた失敗した解決策 #2
配列が だけの同種配列である場合Child_With_Value_Protocol
、型消去を使用して値を取得できます。
これは、構造体AnyValue
に の初期化子がないため、コンパイルに失敗しますParentProtocol
。
試みられた失敗した解決策 #3
他のソリューションとは異なり、このソリューションは実際にコンパイルされます。erased
このソリューションの問題は、配列が の型消去されたバージョンの値しか保持できないという事実にありChild_With_Value_Protocol
ます。目標は、配列が と の両方の型を保持することです 。Child_With_Value_Protocol
ChildProtocol
試みられた失敗した解決策 #4
type-erase 構造体を変更してイニシャライザを含めると、ParentProtocol
コンパイルされるソリューションが作成されますが、構造体はより具体的な init ではなく、より具体的でない init のみを使用します。
ios - Swift - プロトコル拡張 - プロパティのデフォルト値
私が次のプロトコルを持っているとしましょう:
そして、私は次の構造体を持っています:
ご覧のとおり、構造体 A と構造体 B の Identifiable プロトコルに「準拠」する必要がありました。しかし、このプロトコルに準拠する必要がある構造体がさらに N 個あると想像してみてください... 「コピー/貼り付け」したくありません' 適合性 (var id: Int、var name: String)
だから私はプロトコル拡張機能を作成します:
この拡張により、両方のプロパティを実装しなくても、Identifiable プロトコルに準拠する構造体を作成できるようになりました。
問題は、id プロパティまたは name プロパティに値を設定できないことです。
これは、Identifiable プロトコルでは、id と name のみが取得可能であるために発生します。id プロパティと name プロパティを{get set}に変更すると、次のエラーが発生します。
タイプ「C」はプロトコル「識別可能」に準拠していません
このエラーは、プロトコル拡張にセッターを実装していないために発生します...そのため、プロトコル拡張を変更します。
エラーはなくなりましたが、新しい値を id または name に設定すると、デフォルト値 (getter) が取得されます。もちろん、セッターは空です。
私の質問は次 のとおりです。セッター内に配置する必要があるコードはどれですか? self.id = newValueを追加するとクラッシュするため (再帰的)。
前もって感謝します。
ios - プロトコル指向プログラミング、暗黙的に拡張メソッドを呼び出す
POP で私の最初のクラックを持っています。この場合、いくつかの UIViewControllers をデコレートして、「ページ表示」分析イベントを自動的に発生させるようにします。
そこで、プロトコルと、そのプロトコルの拡張機能を作成しました。
UIViewController を次のように装飾すると、これは私が望むように機能しReportPageViewedEvent
ます。
正確に必要な「pageName」を設定しないと、コンパイラ エラーが発生します。
reportPageViewed()
私が行き詰まっているのは、実際のメソッドをどこでどのように呼び出すかです。viewDidLoad
つまり、それを使用するすべてのコントローラーのすべての「viewDidLoad」を変更するか、サブクラス化して、最初にPOPを使用するという点に反するスーパークラスのメソッドを呼び出す必要があります。
これを達成する良い方法はありますか。このような例は、どのチュートリアル/ブログでも見つかりません。
struct - Swift Struct のデフォルトの初期化子を非表示にする方法はありますか?
私はと呼ばれるプロトコルを持っていますParameter
:
また、以下に準拠する 16 の構造体がありますParameter
。
ご覧のとおり、すべての構造体が同じ初期化子を実装しています。イニシャライザでは、プロトコルに必要な 3 つのパラメータのうち 2 つにデフォルト値を指定しParameter
ます。これにより、次のイニシャライザが得られます。
また、構造体によって作成されたデフォルトの初期化子も取得します。
構造体のインスタンスを作成すると、両方の初期化子が Xcode のコード補完ポップオーバーに表示されます。name
ただし、パラメータとunit
パラメータがイニシャライザで提供されるデフォルト値と異なるものになることは望ましくありません。また、構造体の内部で宣言されているが、プロトコルで必要な初期化子の外部で宣言されているname
およびプロパティにデフォルト値を割り当てようとしました。unit
Parameter
Xcodeのコード補完ポップアップにデフォルトのイニシャライザを表示せずに、name
およびunit
パラメータにデフォルト値を指定し、パラメータのみを指定して構造体を初期化する方法はありますか?value
Parameter
両方の初期化子を Xcode のコード補完ポップアップに表示することに関する唯一の懸念は、他の誰かが構造体を作成し、プロトコルで必要な初期化子で提供した値以外の値を提供したくないということです。
クラスでそれができることはわかっていますが、プロトコル指向のプログラミングと構造体の使用について理解を深めようとしています。
ios - プロトコル指向のファイル取得
最近、私はこの講演 (リンク、セクションNetworkingを参照) を見て、プロトコル指向プログラミングの演習を行うことにしました。そこで、この簡単な例について考えました: ファイルのリストを表示するためのビュー コントローラー。もちろん、プロトコル指向の方法で、次の制約があります。
FilesViewController
- テーブル ビュー & が含まれてFilesTableViewAdapter
います。テーブル ビュー デリゲート。
FilesTableViewAdapter
- テーブル ビュー &FilesProvider: Gettable
で初期化できるため、テストで を注入できFilesProviderMock: Gettable
ます。
FilesTableViewAdapter
テーブル ビューのデータ ソースであり、FilesProvider
ファイルのフェッチに使用します。
このコードを一般化しすぎたことはわかっています。今、私は立ち往生しており、自分では答えられないこの質問があります。
- VC とは異なるクラスのネットワーク コード (たとえばAdapter ) を使用して、プロトコル指向の方法で作成するにはどうすればよいですか?
- 将来的に簡単にテスト可能で拡張可能にする方法は?
ios - ios swift クラス準拠プロトコル
私は迅速に学習しようとしており、プロトコル指向のプログラミングアプローチを使用したいと考えています。私が達成したいことは簡単ですが、方法が見つかりませんでした。
テキストフィールドであるアウトレットがあるとしましょう。テキストフィールドが ValidatesName プロトコルのようなプロトコルに準拠することを望みます。それを行う方法はありますか?UITextField をサブクラス化し、プロトコルに準拠する新しいクラスを作成したくありません。この特定のプロパティに使用したい。
ありがとう
swift - プロトコル指向プログラミング拡張変数の init 2 回
これが状況です。プロトコルとその拡張があります。
そして、このプロトコルに準拠する ViewController を作成し、このカスタム 'aView' を ViewController のビューに追加します。
私はそれを実行します。コンソール ログに init が 2 回出力され、カスタム 'aView' で何かをしようとして失敗しました。(上に貼り付けたコードは、意図を示すのが非常に簡単になるように単純化したものです)
誰かが理由を説明したり、修正したりしていただければ幸いです。