首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将文本分配给UILabel时内存泄漏(iOS,Swift 4,Xcode 9)

将文本分配给UILabel时内存泄漏(iOS,Swift 4,Xcode 9)
EN

Stack Overflow用户
提问于 2018-05-12 13:20:14
回答 2查看 1.3K关注 0票数 6

我一直在开发一个没有故事板的新应用程序。在我用仪器测试我的应用程序之前,一切都很顺利:每次我给标签分配一个字符串时,它都会泄露出去。当我用一个故事板工作时,我没有那样的漏洞。

我阅读了以下资料,以找出答案:

最流行的观点是,这是一个仪器缺陷,但它似乎是一个太明显的方法对我。

泄漏在一个空应用程序中再现。在根视图控制器中:

代码语言:javascript
复制
class ViewController: UIViewController {

var label: UILabel?

override func viewDidLoad() {
    super.viewDidLoad()

    label = UILabel()
    view.addSubview(label!)
    var textForLabel: String? = "Hello"
    label?.text = textForLabel

    //attempt to free the memory
    textForLabel = nil
    label = nil

    //EDIT: added after @J.Doe and @Sh-Khan answers, but it's still leaking
    label.removeFromSuperview()

   }
}

在实际设备上测试此应用程序(iPhone SE 11.2)时,我看到了以下内容:

当我单击_NSContiguousString时,我看到内存泄漏出现在UILabel setText:中。

我试图将标签设置为“弱”,但当我试图将它添加为子视图时,它就变成了零。

所以,我的问题是:

  • 我现在和将来怎样才能消除这个内存泄漏?
  • 为此,我应该只在..xib/..storyboard文件中创建UI元素吗?

我是iOS开发的新手,所以我想我遗漏了一些显而易见的东西。我将非常感谢任何帮助或建议。

编辑:根据@Sh-Khan@J.Doe的答案(非常感谢你们!),我添加了label.removeFromSuperview(),但仍然有漏洞。

EDIT2:在@J.Doe的帮助下,我了解到UILabel是通过调用removeFromSuperview并将其设置为零从内存中释放出来的。仪器中的内存泄漏仍然存在,但我标记他的答案被接受了,因为这正是我想知道的。

PS:在阅读了关于NSString保留计数的文章后,我认为内存泄漏的原因可能是因为我使用的是一个不能释放的字符串文字。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-12 13:26:09

也许我错了,但我认为:

弱将不会增加参考计数器。因此,将对象标签分配给弱var标签是没有意义的。这是因为弱var标签将为零,因为您创建的对象没有任何引用(因此它将重新初始化)。

让我们计算一下您的代码中有多少引用您创建的对象标签。

代码语言:javascript
复制
label = UILabel() // 1
view.addSubview(label!) // 2
var textForLabel: String? = "Hello"
label?.text = textForLabel

//attempt to free the memory
textForLabel = nil
label = nil // 1

视图中还保留了一个对对象标签的引用。在执行label = nil之前,调用label?.removeFromSuperview()。我想你有0的参考资料,->,它会被删除。

编辑:

将下面的UILabel子类添加到代码中:

代码语言:javascript
复制
class MyLabel: UILabel {
    deinit {
        print("I am gone!")
    }
}

var label: UILabel?更改为var label: MyLabel?

label = UILabel()label = MyLabel()

查一下日志。你看到“我走了”的字样吗?

Edit2:这个印着“我走了!”在一个空项目中,这只作为代码:

代码语言:javascript
复制
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!")
    }
}
票数 3
EN

Stack Overflow用户

发布于 2018-05-12 13:26:58

第一设定

代码语言:javascript
复制
textForLabel = nil

将不会删除或使标签文本为零,因为标签已经获取了它的副本

第二次设定

代码语言:javascript
复制
label = nil 

你要做的还不够

代码语言:javascript
复制
label.removeFromSuperview()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50306683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档