Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift UILabel如何成为CALayer并导致崩溃?_Swift_Memory Management_Ios9 - Fatal编程技术网

Swift UILabel如何成为CALayer并导致崩溃?

Swift UILabel如何成为CALayer并导致崩溃?,swift,memory-management,ios9,Swift,Memory Management,Ios9,我有一个自定义的UIView,其中几个实例是在一个循环中创建的: let models = CDMyModel.MR_findAllSortedBy("position", ascending: true) as! [CDMyModel] for view in myViews { view.removeFromSuperview() } self.myViews.removeAll(keepCapacity: true) for model in models { let

我有一个自定义的
UIView
,其中几个实例是在一个循环中创建的:

let models = CDMyModel.MR_findAllSortedBy("position", ascending: true) as! [CDMyModel]

for view in myViews {
    view.removeFromSuperview()
}

self.myViews.removeAll(keepCapacity: true)

for model in models {
    let myView = MYFaqView(width: CGRectGetWidth(self.view.frame))
    myView.titleLabel.text = model.title
    myView.content.text = model.content
    myView.titleLabel.sizeToFit()
    self.scrollView.addSubview(myView)
    self.myViews.append(myView)
}
我确实有时会看到Crashlytics中的崩溃与
myView.content.text=model.content

根据这次崩溃,我认为它与内存有关,但我真的不知道myView是如何在那时发布的

所有这些都会在
视图中出现:
。之前的移除可能与此有关吗?但是我假设所有的事情都发生在主线程上,所以这也不应该是个问题——我真的被困在这里了

崩溃发生在iOS 9上

编辑

let content:UILabel = {
    let l = UILabel()
    l.numberOfLines = 0
    if let font = UIFont(name: "OpenSans", size: 14) {
        l.font = font
    }
    return l
}()
MyFaqView初始化方法:

init(width:CGFloat) {
    self.width = width

    super.init(frame: CGRectZero)

    self.addSubview(self.titleLabel)
    self.addSubview(self.toggleImageView)
    self.addSubview(self.separatorView)
    self.content.clipsToBounds = true
    self.addSubview(self.content)

    self.translatesAutoresizingMaskIntoConstraints = false
    self.clipsToBounds = true
}
编辑

let content:UILabel = {
    let l = UILabel()
    l.numberOfLines = 0
    if let font = UIFont(name: "OpenSans", size: 14) {
        l.font = font
    }
    return l
}()

简要查看显示了两个潜在问题:

  • 您可以在此处中断迭代器,这会导致未定义的行为-
    removeFromSuperview()
    真正从层次结构中删除视图并释放它,减少MyView中的元素数量
  • 用于在MyView中查看{ view.removeFromSuperview()}

  • 你在这里干什么?看起来你重复了上一步
  • self.myViews.removeAll(keepCapacity:true)


    这些问题总是很难找到

    基本上,正在发生的是内存损坏。先前由
    UILabel
    内容占用的地址
    0x14f822a0
    已被其他内容使用,在本例中为
    CALayer
    。如果本地发生崩溃,您可以通过在lldb中输入
    po 0x14f822a0
    来验证这一点,并确保它将输出
    CALayer
    类型的地址

    对于这些错误,虽然碰撞线可以提供线索,但它并不总是错误的原因。其他地方已经发生了一些事情

    尽管Swift主要是内存管理的,但对于粗心的人来说仍然存在陷阱。就我个人而言,我已经看到了导致记忆衰退的两个主要原因。第一个是由自引用闭包引起的保留循环。第二个与您的问题更相关的是与故事板和XIB相关的视图

    如果我们遵循逻辑,我们可以认为 Calayer-<代码>现在占据了以前由你的代码> uIabele<代码> <强>内容< /强>的地址空间。运行时试图将消息发送到该地址的对象,该消息被Swift运行时断言捕获,该断言随后触发

    EXC\u BAD\u指令
    崩溃

    现在,如果有其他对象在该地址居住,则必须释放
    UILabel
    内容的原始居民。那么为什么运行时会发布内容呢?因为它不再是必需的,也就是说,它不是它仍然需要的任何视图的子视图或属性

    我敢打赌,如果您将content更改为一个子类
    UILabel
    ,并添加一个
    deinit
    方法,然后将其作为断点,您将惊讶地看到它在早期被意外地反初始化。要测试此属性,请创建一个类型,如下所示:

    class DebugLabel: UILabel
    {
       func deinit
       {
         NSLog("Breakpoint on this line here!")
       }
    }
    
    然后将内容的类型更改为上面的
    调试标签

    那么,为什么会发生这一切?我的钱花在你有一个视图属性上,它是通过编程方式创建的,要么是
    弱的
    ,要么是
    无主的
    。也许您以前使用
    IBOutlet
    设置了这些,然后您删除了它,但忘记删除
    weak
    指示符


    仔细检查每一个问题,我相信您会找到上述问题的原因。使用初始化器或
    UINib
    以编程方式创建的任何内容都不应指定为
    weak
    unowned

    您是否可以包含
    MYFaqView
    的init方法的源代码?显示内容视图/标签的初始化?使用Zombies工具在Instruments下运行。它找到僵尸了吗?
    myViews
    是我在
    updateViewConstraints
    中需要的所有视图的数组,所以
    removeAll
    实际上并没有将它们从视图层次结构中移除-我想这没有问题,对吧?为什么不只使用scrollView.subview呢?试着从MyView中删除依赖项,看看会发生什么问题是它不会经常崩溃,对大多数用户来说它不会崩溃-我无法一次重现它,但在crashlytics中,我看到在那个地方有多个崩溃,所以我不知道我是否解决了这个问题MYFaqView init里面有什么?@MaratAl永远不要使用
    scrollView.subview
    。它包含滚动视图指示器,即使这些指示器是隐藏的,你也不应该弄乱它们。