Каковы недостатки наследования всех классов от NSObject? - PullRequest
1 голос
/ 05 ноября 2019

Я запускаю новый проект iOS Swift. Мне нужно добавить некоторые функции, которые должны наследовать все классы проекта. В отличие от Objective C не все классы в Swift наследуются от какого-либо конкретного класса, например NSObject. Например,

Я не могу создать расширение класса Any или AnyObject, как я могу для NSObject. Например, приведенный ниже код в порядке.

extension NSObject {

    @objc var classTag: String {
        return String(describing: type(of: self))
    }
}

Но расширение на AnyObject дает ошибку компилятора,

Неноминальный тип 'AnyObject' не может быть расширен

Итак, я решил сделать все быстрые классы в моем проекте наследуемыми от моего BaseClass, который на самом деле наследуется от NSObject.

class BaseClass: NSObject {

    @objc var classTag: String {
        return String(describing: type(of: self))
    }
}

И других классов, т. Е.

class OtherClass: BaseClass {
    // have classTag
}

Прежде чем я создам политику для своей команды, чтобы наследовать все классы от BaseClass, я хочу знать, есть ли некоторые недостатки наследования всех классов от NSObject по умолчанию.

Ответы [ 2 ]

1 голос
/ 05 ноября 2019
  • Классы, унаследованные от NSObject, не могут быть final. Хотя оптимизация всего модуля включена, Swift добавит final, когда это возможно, но не в целевых c классах. Это микрооптимизация, и я действительно не буду рассматривать, если у вас нет особого случая.
  • При рассмотрении вопроса об использовании семантики копирования (использования структур) вы не сможете расширять свои структуры путем наследования.
  • Вы добавите много шума при автозаполнении в IDE.
  • Использование протоколов (POP) может дать вам больше гибкости / мощности. Например, условное соответствие и т. Д. И при необходимости вы можете расширить NSObject.

Попробуйте использовать protocol extension и, возможно, структуры вместо NSObject.

protocol Base {
  func work()
}

extension Base {
  func work() {...}
}

struct AppState: Base {}

AppState().work()
1 голос
/ 05 ноября 2019

Я не думаю, что есть даже необходимость наследовать от NSObject, если вы делаете BaseClass для наследования другими классами.

Вы можете просто добавить classTag в BaseClass сам, т.е.

class BaseClass {
    var classTag: String {
        return String(describing: type(of: self))
    }
}

class SubClass: BaseClass {
    func someFunc() {
        print(self.classTag)
    }
}

Другой вариант может состоять в том, чтобы использовать protocol и protocol extension и предоставить определение по умолчанию classTag, т.е.

protocol SomeProtocol {
    var classTag: String { get }
}

extension SomeProtocol {
    var classTag: String {
        return String(describing: type(of: self))
    }
}

Затем выможет соответствовать SomeProtocol классам, где это необходимо, т.е.

class SubClass: SomeProtocol {
    func someFunc() {
        print(self.classTag)
    }
}

В любом случае наследование от NSObject не требуется, так как для этого вам не нужны специальные функции NSObject.

...