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

后端 未结 2 2086
忘了有多久
忘了有多久 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!")
        }
    }
    
    0 讨论(0)
  • 2021-01-05 14:55

    First setting

    textForLabel = nil
    

    won't remove or make the label text nil as the label already took a copy of it

    second setting

    label = nil 
    

    is not enough you have to

    label.removeFromSuperview()
    
    0 讨论(0)
提交回复
热议问题