私は最近、Objective-C でプロトコルを使用する方法を (Apple の公式ガイドを使用して) 学んでいますが、矛盾しているように思われるものを理解するのに苦労しています。ドキュメントには、次のように記載されています-
プロパティに必要なプロトコル準拠を指定すると、基本的なプロパティ クラスの型がジェネリックであっても、プロパティをプロトコルに準拠しないオブジェクトに設定しようとすると、コンパイラの警告が表示されます。
そこで、「XYZFakeProtocol」というプロトコルと、このプロトコルに準拠しない「XYZPerson」というクラスを作成して、これをテストします。次に、次のように XYZFakeProtocol に準拠することが期待される汎用クラス変数を初期化しようとします -
id <XYZFakeProtocol> speakingPerson = [[XYZPerson alloc] init];
予想通り、XCode はエラーにフラグを立てます -
<
互換性のないタイプ「XYZPerson *」の式で「__strong id XYZFakeProtocol>」を初期化しています
ただし、同じことを行っても、インスタンスを手動で割り当てて初期化するのではなく、ファクトリ メソッドを使用すると、エラーは発生しません。私が使用したコードで、ファクトリ メソッドは「person:」です。
id <XYZFakeProtocol> speakingPerson = [XYZPerson person];
エラーはフラグされず、特に問題なのは、プロトコルで指定されたメソッドを呼び出したときに、そのメソッドが実際には非準拠クラスにない場合でもコンパイラ エラーが表示されないことです。これにより、プログラムがクラッシュします。
これは Xcode の問題ですか、それともファクトリ メソッドを使用した場合の予想される正しい結果ですか。実際のアプリケーションのコーディング?
参考までに、XYZPerson オブジェクトを作成して XYZPerson 変数に代入し、その変数をジェネリック型変数に代入すると、インスタンスが を使用して作成されたかどうかに関係なく、Xcode はクラスがプロトコルに準拠していないというエラーを正しくフラグ付けします。ファクトリメソッドまたは手動で初期化 -
XYZPerson *helloPerson = [XYZPerson person];
XYZPerson *helloPerson2 = [[XYZPerson alloc] init];
id <XYZFakeProtocol> speakingPerson = helloPerson;
speakingPerson = helloPerson2;
ありがとう。