【问题标题】:Initializing a xib on a UIViewController's subview在 UIViewController 的子视图上初始化 xib
【发布时间】:2016-11-25 03:50:34
【问题描述】:

当 UITableView 中没有可显示的内容时,我使用 DZNEmptySet 进行加载。它适用于 DZNEmptySet 的方法,如 titleForEmptyDataSetimageForEmptyDataSet,但不是我想要使用的方法(即 customViewForEmptyDataSet)。

当我尝试将 xib 加载到 scrollView.frame 时,Xcode 的内存开始以 30 兆字节的增量膨胀,并且应用程序挂起。我知道我有错,但我不知道我在搞砸什么。

我在这里查看了很多答案和其他网站上的教程,但我找不到适合这种情况的解决方案(我认为这很简单)。任何有关这方面的反馈将不胜感激。

这是customViewForEmptyDataSet MyViewController

// App hangs on this and memory bloats in 30 megabyte increments.
func customViewForEmptyDataSet(scrollView: UIScrollView!) -> UIView! {
    return EmptySetView(frame: scrollView.frame)
}

这是我正在尝试初始化的 EmptySetView 的类:

import UIKit

class EmptySetView: UIView {
    var view: UIView!
    // These are connected to a xib
    @IBOutlet weak var backgroundImageView: UIImageView!
    @IBOutlet weak var viewLabel: UILabel!
    @IBOutlet weak var viewTextView: UITextView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        self.addSubview(self.view)
    }

    func loadViewFromNib() -> UIView {
        let bundle = NSBundle(forClass:self.dynamicType)
        let nib = UINib(nibName: "EmptySetView", bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView

        return view
    }
}

更新

Matt's suggestion,我调查了我遇到的递归并发现了问题的根源。

您没有在 xib 的 View 上指定 UIView 类。相反,您单击标题为 File's Owner 的黄色立方体并在其中指定 UIView,在 Document Outline 面板的 View 上将类字段留空。

清理缓存和重建后,我可以使用在MyViewController 上调用的这段代码将视图加载到层次结构中:

func customViewForEmptyDataSet(scrollView: UIScrollView!) -> UIView! {
    let emptySetView = EmptySetView(frame: scrollView.frame)
    return emptySetView
}

在加载 xib 之前,EmptySetView xib 和 MyViewController 彼此不知道,因此您需要处理布局约束。

【问题讨论】:

  • 你从哪里调用'customViewForEmptyDataSet'
  • 使用仪器。它会立即告诉您问题的根源是什么。您可以观察内存增长并查看导致它的调用链。
  • @NickCatib customViewForEmptyDataSet 是一个委托方法,如果 tableView 为空,则会调用该方法。
  • @matt 我把它放在 Instruments for Leaks 中,我认为我的问题在于 ` required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() }. I think the setup()` 调用导致问题。我看过的每个示例都有 init frame 和 init coder w/ 看起来几乎相同。我会继续努力,放心,我正在做一些非常愚蠢的事情。
  • 我确定你在无限递归,但我太累了,无法告诉你在哪里。调试器会立即显示给您。

标签: ios swift autolayout scrollview xib


【解决方案1】:

我的猜测是,在您正在加载的 nib 中,顶层视图本身就是一个 EmptySetView。这导致了递归。您首先在代码中实例化 EmptySetView:

override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

setup() 中,加载笔尖。但这会导致 EmptySetView 从笔尖再次实例化。这一次,调用了另一个初始化器:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
}

但是setup() 加载了笔尖,所以我们现在绕着圈子,试图像 matrushka 娃娃一样将无数个加载笔尖的视图嵌套在一起。

【讨论】:

  • 谢谢!我在解决递归问题方面取得了一些进展。视图现在加载,但在加载时似乎没有遵守 xib 上指定的自动布局约束。我更新了我的问题。
  • 很抱歉,但我觉得这不像是更新:这是一个完全不同的问题。看来我的回答是对的;我觉得你应该接受。如果您有新问题,请作为不同的问题提出,如果可以的话,我很乐意提供帮助。否则你只是在偷窃——把你的问题变成一个移动的目标,没有人可以从中获得“接受”复选标记,并“免费”寻求越来越多的帮助。
  • 介意如果我编辑你的答案添加一个应该检查文件所有者指定 UIView 类,而不是 xib 中的视图?这就是导致递归的原因。
  • 导致递归的原因是我所说的:您已将顶级视图的类设置为 EmptySetView。这与文件的所有者无关。文件的所有者可以是任何东西。它应该是在 nib-loading 时将成为所有者的类,但这与您遇到的问题无关。 (当然,如果 File's Owner 不是正确的类,您将遇到不同的问题,因为您的 outlet 将无法工作;但这不是问题所在。)
  • 顺便说一句,您可能想阅读我的书以了解加载笔尖的过程:apeth.com/iOSBook/ch07.html#_nib_loading_and_file_8217_s_owner 您似乎因为笔尖和笔尖加载而有些挣扎。
猜你喜欢
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
相关资源
最近更新 更多