I have an Objective-C category that I\'d like to add to multiple classes without duplicating the code contained in the category. I simply want to add the same methods to multipl
I'm still unaware of a clean way to do this in Objective-C, but with Swift 2.0 this can be implemented using Protocol Extensions by adding functions and/or properties to an existing protocol. The protocol can then be adopted by an arbitrary number of classes, structs, and/or enums.
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())")
correctly implements number()
on all three classes (Book
, Chapter
, Page
):
myBook.number() = 5
myChapter.number() = 2
myPage.number() = 8
Why not make the shared code class level methods in a central class, that you simply call via shell methods in each of your categories?
If your categories are storing associated references you could pass those into the class level methods to act on.
It's a bit of a misnomer to say that providing a category on nsmanagedobject "has the unintended consequence of adding the category's methods to all NSManagedObject subclasses.". The category code is just linked when you include it in a file in which you are using it: you aren't modifying nsmanagedobject.
That said, if the code needs to be aware of its object, you could create a protocol to which those classes conform, and then use conformsToProtocol in your code to do the testing. That's probably a better generic approach than testing for specific class types.
It sounds kind of like you want something like a ruby module. I don't know of any way to do such a thing in objective-c. You could make a protocol and make each of your classes conform to your protocol, but that doesn't solve the problem of sharing implementation of the methods.
Check out this question, it might provide some more insights.
maybe it's too late.. But maybe there is one way to do it.. But, you said.. needs to have the same superclass
Category.h
@protocol MyProtocol <NSObject>
- (NSString*)foo;
@end
@interface NSArray (category) <MyProtocol> @end
@interface NSString (category) <MyProtocol> @end
Category.m
@interface NSObject (category) <MyProtocol> @end
@implementation NSObject (category)
- (NSString*)foo
{
return @"bar";
}
@end
I don't like this neither, but it works
For the rest of your stuff there, as far as I know you would have to go back and make a common subclass for your three classes to get what you want. But what I can point out is that instead of doing your own isSupported method there it would probably be better to simply use the respondsToSelector method of NSObject to tell if your class implements whatever special method you want those three classes to use, which should be better than checking against all those classes. Defiantly better if you add additional classes as you don't have to maintain or expand that giant list of isMemberOfClass checks