iOS内存泄漏与笔尖

时间:2018-02-15 14:31:01

标签: ios memory-leaks automatic-ref-counting awakefromnib uinib

class CView: UIView {

    // MARK: - class

    class func nibView(frame: CGRect, assertion: Assertion?,contentReference: ContentReference?, delegate : AssertionViewDelegate? = nil) -> CView {
        let view =  UINib(nibName: "CView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CView // LEAK
        view.delegate = delegate
        if let assertion = assertion {
            view.configure(for: assertion, contentReference: contentReference)
        }
        return view
    }
    }

在UITableViewCell内部,我在init

中添加了这个视图
func initializeViews(){
 if cview == nil {
    self.isOpaque = true
    let view = CView.nibView(frame: CGRect(x: 0, y: 0, width: Int(self.bounds.width), height: 0), assertion: nil, contentReference: nil)
    self.contentView.addSubview(view)
    self.cview = view

    self.cview.translatesAutoresizingMaskIntoConstraints = false
    self.cview.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true
    self.cview.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true
    self.cview.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
    self.cview.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true
}

}

func configureAssertion(){
    initializeViews()
    assertionView.tag = self.tag
   self.cview.configure() // configure with model
}

这会造成泄漏 - let view = UINib(nibName: "CView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CView // LEAK

I have edited, checking for nil before assigning. And I am calling initializeViews inside configure. But still seeing the leak.

1 个答案:

答案 0 :(得分:1)

你的解决方案看起来很奇怪。通常,您可以通过注册它来创建UITableViewCell并将其出列:

// in your UIViewController class
func viewDidLoad() {
    super.viewDidLoad()
    // a) register a cell defined by nib
    tableView.register(UINib(nibName: "MyCellNibName", bundle: Bundle.main), forCellReuseIdentifier: "MyCellIdentifier")
    // b) register a cell defined by code
    tableView.register(MyCellClassName.cellClass, forCellReuseIdentifier: "MyCellIdentifier")
}

// in your tableView's datasource implementing class (maybe your UIViewController class)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyCellIdentifier", for: indexPath) as! MyCellClassName
    // configure cell
    return cell
}

可以在// configure cell部分的contentView中添加子视图,但您必须确保它之前尚未添加。请注意,dequeueReusableCell可能会为您提供一次已使用过的单元格并滚动到视线之外(因此系统可以重复使用它)。

在任何情况下,在UITableViewCell init中添加子视图都是完全错误的,而且是针对可重用单元格的设计。

您没有添加所有代码,因此请检查CView :: delegate是否也定义为弱。

另请注意:避免使用任何init内部的功能是一种很好的做法。初始化对象应该很快。从体系结构的角度来看,除了仅在那里分配依赖项之外,没有理由做更多的事情。从你班级用户的角度来看,如果一个简单的YourClass(..)已经做了一些魔术,那就完全出乎意料了。