58
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift(一人)Advent Calendar 2015

Day 9

Swiftのprotocolに付ける : class を理解する

Posted at

下のようなコードですが、weak cannot be applied to non-class type 'MyProtocol'というエラーになります。

protocol MyProtocol {}

// weak cannot be applied to non-class type 'XXX'
class MyClass {
    weak var delegate: MyProtocol?
}

エラーの解決策

protocolに:classを付与すれば直ります。

protocol MyProtocol: class {}

class MyClass {
    weak var delegate: MyProtocol?
}

: classとは何か

:classを付けるとこのProtocolはclassにのみ適用できるようになります。
:classが付いている場合、enumやstructにはこのプロトコルを使えないです。

// : classなし
protocol MyProtocol {}

class MyClass: MyProtocol {}
struct MyStruct: MyProtocol {}
enum MyEnum: MyProtocol {}
// : classあり
protocol MyProtocol: class {}

class MyClass: MyProtocol {}
struct MyStruct: MyProtocol {} // エラー
enum MyEnum: MyProtocol {} // エラー

: classはあるのですが、: struct: enumはありません。

protocol MyProtocol: struct {} // エラー
protocol MyProtocol: enum {} // エラー

なぜ: classを付けないとエラーになるのか

それはstructやenumはweakを付ける事ができないからです。

struct MyStruct {}
enum MyEnum { case A }

class MyClass {
    weak var myStruct = MyStruct() // エラーになる
    weak var myEnum = MyEnum.A // エラーになる
}

なぜstructやenumでweakが使えないのか

おそらくですが、structやenumには参照カウントがないからだと思われます。

クラスを初期化して変数に入れた場合、変数にはオブジェクトのメモリアドレスが入っています。
参照カウントとは、変数がそのオブジェクトを参照した際にインクリメントされて参照がなくなったらデクリメントされるものです。
つまりそのオブジェクトが何個の変数から参照されているかを表すものです。

weakとはオブジェクトを参照しても参照カウントが増えないようにする機能です。

それに対してstructやenumは変数にメモリアドレスでなく値が入っています。
その為参照されると概念がなく、参照カウントもありません。

そういった事もあってstruct/enumでは参照カウントを制御するweakを使えないのだと思われます。

この辺少し自身がないので変な所あればツッコミ頂けると嬉しいです m m

まとめ

  • protocol MyPritocol: classはクラスのみに適用できるようにする記法
  • クラスに絞り込めばweak修飾子を使える
  • structやenumは参照カウントがないのでweakが使えない
58
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?