5
3

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 1 year has passed since last update.

iOSAdvent Calendar 2023

Day 7

weak selfがstructでは使用できず、classで使用できるのはなぜ?

Last updated at Posted at 2023-12-04

weak selfがstructで使用しようとした時に起こったエラー

🟥エラー:'weak' may only be applied to class and class-bound protocol types
'weak'は、クラスおよびクラスにバインドされたプロトコルタイプにのみ適用できるというエラーが起こる。

structとclassの違いとweak self

⚫︎structは値型

⚫︎classは参照型

参照型は3つの参照方法がある!
1.強参照
デフォルトはstrong
2.弱参照
weak
参照先が存在しない場合に参照しようとされると自動でnilになってる
3.非所有参照
unowned
参照先が存在しない場合に参照しようとされると解放済みへのアクセスとなりクラッシュする

structにweak selfが適用できない理由

weakは参照型のための修飾子であり、構造体などの値型とは異なる。
値型はコピーによって割り当てられ、参照カウントは適用されないので、weak修飾子は意味を持ちません。
以下のようなエラーになります。

struct S {
    private var closure: (() -> Void)?
    private var count = 0

    init() {
        closure = createClosure()
    }

    func createClosure() -> (() -> Void) {
//🟥エラー:'weak' may only be applied to class and class-bound protocol types, not 'S'
        return { [weak self] in self?.count += 1 }
    }
}

var s: S? = S() 
s = nil  

classでweak selfの適用例

参照型では、同じオブジェクトに対して複数の参照を持つことができる。
オブジェクトは、最後の強い参照がそのオブジェクトを参照しなくなった時点で解放されます。
classは参照型であるため、weakは参照型のための修飾子が適用できます!
以下のようにclassでweak selfを使用すると、参照先が存在しない場合に参照しようとされると自動でnilになってくれるので、循環参照を防ぐことができます!

class C {
    private var closure: (() -> Void)?
    private var count = 0

    init() {
        closure = createClosure()
    }

    func createClosure() -> (() -> Void) {
        return { [weak self] in self?.count += 1 }
    }
}

var c: C? = C()
c = nil 

参考文献

5
3
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?