Добавление одной и той же категории в несколько классов

у меня есть категория Objective-C, которую я хотел бы добавить в несколько классов без дублирования кода, содержащегося в категории. Я просто хочу добавить одни и те же методы к нескольким классам.

у меня есть существующие категории на NSManagedObject подклассы (Book, Chapter, Page) и я хотел бы добавить общую функциональность во всех этих подклассах чистым и доступным способом.

один из способов-добавить категорию в их общий суперкласс (NSManagedObject), но это имеет следствием добавления методов категории ко всем NSManagedObject подклассы, когда я хочу добавить методы к трем подклассам NSManagedObject (Book, Chapter, Page).

другим решением было бы подкласс NSManagedObject а потом Book, Chapter и Page наследовать от этого NSManagedObject подкласс. Это самый чистый, самый прямой подход. Большой недостаток этого подхода заключается в изменении модели данных и регенерации Xcode подклассы, он сбросит их обратно на наследование от NSManagedObject вместо SubclassedManagedObject. Я хотел бы избежать, используя что-то вроде mogenerator/извлеченное имя файла бы, если это возможно.

можно ли добавить одну категорию на несколько классов без дублирования кода?

спасибо.

6 ответов


может быть, уже слишком поздно.. Но, возможно, есть один способ сделать это.. Но ты сказал.. должен иметь тот же суперкласс


Почему бы не сделать методы уровня общего кода класса в Центральном классе, которые вы просто вызываете с помощью методов оболочки в каждой из ваших категорий?

Если ваши категории хранят связанные ссылки, вы можете передать их в методы уровня класса, чтобы действовать.


Я все еще не знаю чистого способа сделать это в Objective-C, но с Swift 2.0 это может быть реализовано с помощью расширений протокола путем добавления функций и/или свойств к существующему протоколу. Затем протокол может быть принят произвольным числом классов, структур и/или перечислений.

protocol Numbered {
    func number() -> Int
}

extension Numbered {
    func number() -> Int {
        return Int(arc4random()) % 10
    }
}

class Book : Numbered {

}

class Chapter : Numbered {

}

class Page : Numbered {

}

let myBook = Book()
let myChapter = Chapter()
let myPage = Page()

print("myBook.number() = \(myBook.number())")
print("myChapter.number() = \(myChapter.number())")
print("myPage.number() = \(myPage.number())")

правильно реализует number() на всех трех классах (Book, Chapter, Page):

myBook.number() = 5
myChapter.number() = 2
myPage.number() = 8

для остальных ваших вещей там, насколько я знаю, вам придется вернуться и сделать общий подкласс для ваших трех классов, чтобы получить то, что вы хотите. Но я могу указать, что вместо того, чтобы делать свой собственный метод isSupported там, вероятно, было бы лучше просто использовать метод respondsToSelector NSObject, чтобы сказать, реализует ли ваш класс любой специальный метод, который вы хотите использовать эти три класса, что должно быть лучше, чем проверка против всех этих классов. Вызывающе лучше, если вы добавляете дополнительные классы, поскольку вам не нужно поддерживать или расширять этот гигантский список проверок isMemberOfClass


похоже, вы хотите что-то вроде модуля ruby. Я не знаю, как это сделать в objective-c. Вы можете сделать протокол и сделать каждый из ваших классов соответствующим вашему протоколу, но это не решает проблему совместного использования реализации методов.

проверить этот вопрос, это может дать больше информации.


немного неправильно говорить, что предоставление категории на nsmanagedobject "имеет непреднамеренное последствие добавления методов категории ко всем подклассам NSManagedObject.". Код категории просто связан, когда вы включаете его в файл, в котором вы его используете: вы не изменяете nsmanagedobject.

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