开发者

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

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 does开发者_开发问答n't seem to be valid. How do I define a category that adds methods to classes which implement a particular protocol?


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.


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

Defining categories for protocols in Objective-C?


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜