0

我正在尝试使用IBInspectable为我的视图添加边框。

extension UIView {

    private func getBorder(integer: Int) -> UIRectEdge {
        if integer == 1 {
            return .top
        } else if integer == 2 {
            return .left
        } else if integer == 3 {
            return .right
        } else if integer == 4 {
            return .bottom
        }
        return .all

    }

    @IBInspectable var border: Int? {
        get {
            return self.border
        }
        set (value) {
            self.border = value
            for v in addBorder(edges: self.getBorder(integer: self.border!)) {
                self.addSubview(v)
            }
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return self.borderColor
        }
        set (value) {
            self.borderColor = value //EXC_BAD_ACCESS here
            for v in addBorder(edges: self.getBorder(integer: self.border!), color: borderColor!) {
                self.addSubview(v)
            }
        }
    }

    private func addBorder(edges: UIRectEdge, color: UIColor = UIColor.white, thickness: CGFloat = 1) -> [UIView] {
        ...
    }
}

崩溃发生在线上self.borderColor = value(在setfor 中borderColor)。

它在调试日志中所说的只是(lldb). 崩溃本身说:

线程 1:EXC_BAD_ACCESS(代码=2,地址=0x7fff53cc5fe8)

这是我的故事板:

故事板

我该如何解决这个问题?谢谢!

4

1 回答 1

1

你在那里有一个无限递归,这导致了崩溃。基本上在borderColor你的 setter 中调用相同属性的 setter,导致无限递归。

发生这种情况是因为类扩展不允许存储属性,因此 Swift 不会为您的属性生成后台存储,而是将其视为计算属性,并在您尝试设置属性时调用 setter。

目前我能想到两种解决方案,可以解决您的问题:

  1. 子类 UIView,在那里添加两个属性,更新 IB 中的类以匹配新类的名称。
  2. UIView在访问器 ( objc_setAssociatedObject()/ )中使用关联对象,objc_getAssociatedObject()而不是直接 iVar 引用。您不需要子类化和更新您的 xib,但是这个解决方案比第一个解决方案有点混乱。
于 2016-08-29T06:57:10.740 回答