EXC_BAD_ACCESS 使用 IBInspectable
EXC_BAD_ACCESS Using IBInspectable
我正在尝试使用 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
行(在 borderColor
的 set
行)。
它在调试日志中所说的只是 (lldb)
。崩溃本身说:
Thread 1: EXC_BAD_ACCESS (code=2, address=0x7fff53cc5fe8)
这是我的故事板:
我该如何解决这个问题?谢谢!
你那里有一个无限递归,这是导致崩溃的原因。基本上在 borderColor
的 setter 中,您为相同的 属性 调用 setter,导致无限递归。
发生这种情况是因为 class 扩展不允许存储属性,因此 Swift 不会为您的 属性 生成后备存储,而是将其视为计算 属性,并在您尝试设置 属性.
时调用 setter
目前我能想到的有两种解决方案,可以解决您的问题:
- Subclass UIView,在那里添加两个属性,更新 IB 中的 class 以匹配新 class.
的名称
- 在您的
UIView
访问器 (objc_setAssociatedObject()
/ objc_getAssociatedObject()
) 中使用关联对象,而不是直接引用 iVar。你不需要 subclass 和更新你的 xibs,但是这个解决方案比第一个解决方案有点混乱。
我正在尝试使用 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
行(在 borderColor
的 set
行)。
它在调试日志中所说的只是 (lldb)
。崩溃本身说:
Thread 1: EXC_BAD_ACCESS (code=2, address=0x7fff53cc5fe8)
这是我的故事板:
我该如何解决这个问题?谢谢!
你那里有一个无限递归,这是导致崩溃的原因。基本上在 borderColor
的 setter 中,您为相同的 属性 调用 setter,导致无限递归。
发生这种情况是因为 class 扩展不允许存储属性,因此 Swift 不会为您的 属性 生成后备存储,而是将其视为计算 属性,并在您尝试设置 属性.
时调用 setter目前我能想到的有两种解决方案,可以解决您的问题:
- Subclass UIView,在那里添加两个属性,更新 IB 中的 class 以匹配新 class. 的名称
- 在您的
UIView
访问器 (objc_setAssociatedObject()
/objc_getAssociatedObject()
) 中使用关联对象,而不是直接引用 iVar。你不需要 subclass 和更新你的 xibs,但是这个解决方案比第一个解决方案有点混乱。