简体   繁体   中英

iOS category conforms to a protocol with properties: how to implement

I have a category on a class I made, and that category conforms to a protocol, which requires a property in its implementation. However, because I'm in a category, I cannot synthesize the property in the implementation of the category. Because of this, I'm stumped on how to implement the setter method (when I keep the protocol's property readonly it works fine, since all I need is an accessor method).

This is my protocol:

@protocol SomeProtocol <NSObject>
@property (nonatomic) BOOL didDisplayRecommendation;
@end

I know if I do this I'll get an infinite loop:

- (void)setDidDisplayRecommendation:(BOOL)didDisplayRecommendation
{
    self.didDisplayRecommendation = didDisplayRecommendation;
}

But when I try this I get a compiler error:

- (void)setDidDisplayRecommendation:(BOOL)didDisplayRecommendation
{
    _didDisplayRecommendation = didDisplayRecommendation;
}

Note that didDisplayRecommendation is the property in the protocol. What's the best way of getting around this? Thanks in advance!

You are not allowed to add instance variables to a class through categories, see https://stackoverflow.com/a/13000930/171933

Since you need a variable to hold the value of didDisplayRecommendation , you are out of luck of doing this with a category (unless you want to get dirty https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418-CH3g-SW5 ).

I'd recommend re-thinking your architecture to see if you really need to use categories. Subclasses or even Mixins might be the better way to go.

在协议中添加属性时,需要@synthesize它们。

I have a macro that lets you declare "properties" in categories like this:

@implementation NSObject (AwesomeUtils)

JESynthesize(assign, NSInteger, index, setIndex);
JESynthesize(strong, NSString *, name, setName);
JESynthesize(copy, void(^)(void), completion, setCompletion);
JESynthesize(unsafe_unretained, id, unsafeObject, setUnsafeObject);
JESynthesize(weak, id<UITableViewDelegate>, delegate, setDelegate);
JESynthesize(strong, NSString *, readonlyID, changeReadonlyID);

// …
@end

I say "properties" with quotes because you can use them even without the @property declaration. The macro also works around to support weak .

You can check the implementation here (the header files are at the bottom): http://nspicks.com/2013/12/15/cleaner-properties-implementation-in-categories/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM