Memory leaks when assigning text to UILabel (iOS, Swift 4, Xcode 9)

后端 未结 2 2088
忘了有多久
忘了有多久 2021-01-05 14:46

I\'ve been working on a new app with no storyboard. All went fine until I tested my application with Instruments: it leaked every time I assigned a string to a label. When I

2条回答
  •  北荒
    北荒 (楼主)
    2021-01-05 14:51

    Maybe I am wrong, but I think this:

    Weak will not increase the reference counter. Therefore, assigning a object label to a weak var label, does not make sense. This is because weak var label will be nil, because the object you created does not have any reference (and therefore it will deinitialize)

    Let's count how many reference you have in your code to your created object Label.

    label = UILabel() // 1
    view.addSubview(label!) // 2
    var textForLabel: String? = "Hello"
    label?.text = textForLabel
    
    //attempt to free the memory
    textForLabel = nil
    label = nil // 1
    

    You have 1 reference left in your view to your object Label. Before you do label = nil, call label?.removeFromSuperview(). I think than you have 0 references -> it will deinit.

    edit:

    Add below subclass of UILabel into your code:

    class MyLabel: UILabel {
        deinit {
            print("I am gone!")
        }
    }
    

    Change var label: UILabel? to var label: MyLabel?

    And

    label = UILabel() to label = MyLabel()

    And check to logs. Do you see the print "I am gone!"?

    Edit2: this prints "I am gone!" in a empty project with this only as code:

    import UIKit
    
    class ViewController: UIViewController {
    
        var label: MyLabel?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            label = MyLabel()
            view.addSubview(label!)
            let textForLabel: String? = "Hello"
            label?.text = textForLabel
    
            //EDIT: added after @J.Doe and @Sh-Khan answers, but it's still leaking
            label?.removeFromSuperview()
            label = nil
    
    
        }
    }
    
    class MyLabel: UILabel {
        deinit {
            print("I am gone!")
        }
    }
    

提交回复
热议问题