EXC_BAD_ACCESS Использование 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 = valueset для borderColor).

В журнале отладки написано только (lldb). Сама авария говорит:

Тема 1: EXC_BAD_ACCESS (код = 2, адрес = 0x7fff53cc5fe8)

Вот моя раскадровка:

раскадровка

Как я могу решить эту проблему? Спасибо!


person Pranav Wadhwa    schedule 29.08.2016    source источник


Ответы (1)


У вас там бесконечная рекурсия, которая вызывает сбой. По сути, в установщике borderColor вы вызываете установщик для того же свойства, что приводит к бесконечной рекурсии.

Это происходит из-за того, что расширениям классов не разрешено иметь сохраненные свойства, поэтому Swift не создает резервное хранилище для вашего свойства, вместо этого он обрабатывает его как вычисляемое свойство и вызывает установщик всякий раз, когда вы пытаетесь установить свойство.

В настоящее время я могу придумать два решения, которые решат вашу проблему:

  1. Подкласс UIView, добавьте туда два свойства, обновите класс в IB, чтобы он соответствовал имени вашего нового класса.
  2. Используйте связанные объекты в ваших UIView средствах доступа (objc_setAssociatedObject()/ objc_getAssociatedObject()) вместо прямой ссылки на iVar. Вам не нужно создавать подклассы и обновлять свои xib, однако это решение немного сложнее, чем первое.
person Cristik    schedule 29.08.2016