سؤال

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.

نصائح أخرى

When you add properties in a protocol you need to @synthesize them.

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/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top