How do I define a category that adds methods to classes which implement a particular protocol?

蓝咒 提交于 2019-12-08 02:49:57

问题


I want to add some methods to subclasses of NSManagedObject that implement the SOManagedObject protocol. I've tried defining it like this:

@interface NSManagedObject <SOManagedObject> (MyExtensionMethods)
    ...
@end

...but that doesn't seem to be valid. How do I define a category that adds methods to classes which implement a particular protocol?


回答1:


Defining such a category on all such classes in general is not easily solvable. But your actual problem seems simpler: How does one add a category method to NSManagedObject for use only with subclasses that implement <SOManagedObject>? This is solvable.

What you want to do is add the method to NSManagedObject, then check that the instance you're working with can handle the messages you want to send it from <SOManagedObject>.

Let us suppose that we are given:

/* SOManagedObject.h */
@protocol SOManagedObject
- (void)frobble_so;
- (void)bobble_so;
@end

Now let's add a category method to all NSManagedObject subclasses that implement SOManagedObject:

/* NSManagedObject+SOConvenience.h */
@interface NSManagedObject (SOConvience)
/* Frobbles and bobbles - no effect on non-<SOManagedObject>-conforming
 * instances. */
- (void)frobbleAndBobble_so;
@end

To do so, we implement the method like so:

/* NSManagedObject+SOConvenience.m */
@implementation NSManagedObject (SOConvenience)
- (void)frobbleAndBobble_so
{
    if (![self conformsToProtocol:@protocol(SOManagedObject)]) return;

    NSLog(@"%s: Thunderbirds are GO! Let's frobble and bobble!", __func__);
    [self frobble_so];
    [self bobble_so];
}
@end

You could optionally assert to ensure you are not sending the method to the wrong objects, or you could use respondsToSelector: instead of checking for protocol conformance. Whatever floats your boat, but this general tack should take you where you want to go.




回答2:


I don't think it is possible. A similar question to this was answered earlier:

Defining categories for protocols in Objective-C?




回答3:


Edit: I misread the question; I don't think it's possible to do what you're trying to do without messing with the Objective-C runtime. See Dave's comment below for why my answer is incorrect.


You should be able to do this if you swap the protocol and category notation like so:

@interface NSManagedObject (MyExtensionMethods) <SOManagedObject>
    ...
@end



回答4:


Adam Sharp posted a solution that worked for me.

It involves 3 steps:

  1. Defining the methods you want to add as @optional on a protocol.
  2. Making the objects you want to extend conform to that protocol.
  3. Copying those methods into those objects at runtime.

Check out the link for the full details.



来源:https://stackoverflow.com/questions/7209967/how-do-i-define-a-category-that-adds-methods-to-classes-which-implement-a-partic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!