質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

393閲覧

特定の親クラスを継承、プロトコルに準拠したサブクラスからプロトコルのプロパティにアクセスしたい

wai21

総合スコア32

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/11/03 04:58

編集2017/11/03 13:02

###前提・実現したいこと
特定の親クラスを継承、プロトコルを準拠したサブクラスからプロトコルのプロパティにアクセスできない

###発生している問題・エラーメッセージ

EXC_BAD_ACCESS (code=1, address=0x0).

###該当のソースコード

swift

1protocol MyProtocol where Self: OyaClass { 2 var protocolPropaty: String {get} 3} 4 5class OyaClass: UIView { 6} 7 8class KoClass1: OyaClass, MyProtocol { 9 var protocolPropaty: String { 10 return "KoClass1" 11 } 12} 13class KoClass2: OyaClass, MyProtocol { 14 var protocolPropaty: String { 15 return "KoClass2" 16 } 17} 18 19class CreateClass { 20 static func createKoClass(para: Int) -> MyProtocol? { 21 switch para { 22 case 1: 23 return KoClass1() 24 case 2: 25 return KoClass2() 26 default: 27 return nil 28 } 29 } 30} 31 32class SomeClass { 33 var array = Array<MyProtocol>() 34 35 func createKoClass(para: Int) { 36 if let koClass = CreateClass.createKoClass(para: para) { 37 array.append(koClass) 38 } 39 } 40 41 func someMethod() { 42 for element in array { 43 print(element.protocolPropaty) 44 } 45 } 46} 47 48var someClass = SomeClass() 49someClass.createKoClass(para: 1) 50someClass.createKoClass(para: 2) 51someClass.someMethod()

KoClass1, KoClass2はそれぞれOyaClassをスーパークラスとして継承し、MyProtocolプロトコルに準拠しています。
CreateClass.createKoClassKoClass1, KoClass2いずれも返せるように返り値の型をMyProtocolとしています。
上記ソースの最終行someClass.someMethod()を実行した際のMyProtocolprotocolPropatyへのアクセス時にEXC_BAD_ACCESS (code=1, address=0x0).が発生してしまいます。

また、KoClass1, KoClass2の親クラスであるUIViewOyaClassのプロパティにもアクセスできるようにしたいと考えています。
そのためにはCreateClass.createKoClassの返り値、SomeClass.arrayの型をOyaClassを継承し、MyProtocolに準拠したクラスと定義すべきと考えているのですが、どのようにすべきでしょうか。

###補足情報(言語/FW/ツール等のバージョンなど)
Xcode 9.1
swift 4.0.2
Playground

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

BAD_ACCESS になるの、面白いですね。

MyProtocol 自身は OyaClass に準拠している型でない限り protocolPropaty を持たないはずなのに Array<MyProtocol> の要素に対してコンパイルが通ってしまうところ、とても興味深いです。そして BAD ACCESS で落ちてしまう…ところも。

そのためにはCreateClass.createKoClassの返り値、SomeClass.arrayの型をOyaClassを継承し、MyProtocolに準拠したクラスと定義すべきと考えているのですが、どのようにすべきでしょうか。

ここに注目すると、型情報を MyProtocol だけでなく OyaClass & MyProtocol にすると "OyaClassを継承し、MyProtocolに準拠したクラス" として定義できます。

swift:要所だけ抜粋

1class CreateClass { 2 static func createKoClass(para: Int) -> (OyaClass & MyProtocol)? { 3 switch para { 4 case 1: 5 return KoClass1() 6 case 2: 7 return KoClass2() 8 default: 9 return nil 10 } 11 } 12} 13 14class SomeClass { 15 var array = Array<OyaClass & MyProtocol>() 16

投稿2017/11/04 13:10

TomohiroKumagai

総合スコア441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wai21

2017/11/04 14:08 編集

回答ありがとうございます。 実行時エラーとなる点についてはやはりまだ解決していませんが、確かにコンパイルが通るということ自体に違和感を感じます。 「(親クラス名 & プロトコル名)」という表現方法を初めて知りました。 ご回答いただいた内容で無事解決し、実現したい内容を実現することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問