I always thought that one cannot declare an object property in a category. Until my partner did it in our app\'s code, and it seemed to work.
I went on a SO and Google b
Assotiative storage is the solution. Have a look at this post.
You have always been able to declare an @property
in a category. What you couldn't do -- and still can't -- is declare storage for the property in the category, neither as an instance variable nor via `@synthesize.
However....
@interface MyClass ()
is not a category. It is a class extension and has a distinctly more specific role than a category.
Namely, a class extension can be used to extend a class's @interface, and this includes @properties that can be @synthesized (including synthesizing storage in the modern runtime).
Foo.h:
@interface Foo
@end
Foo.m:
@interface Foo()
@property int x;
@end
@implementation Foo
@synthesize x; // synthesizes methods & storage
@end
it simply uses associative storage behind the scenes to make this work?
Nope -- it is a real instance variable. The modern runtime fixes the fragile base class problem.
@interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
@end
The above doesn't work (as expected) because foobar
is, effectively, a global variable.
If you change it to:
@interface MyClass () {
NSInteger foobar;
}
- (void) someCategorizedMethod;
@end
Then it'll work with the latest release of the llvm compiler (with the right flags, as @Joshua indicated in a comment).
Generally speaking, properties are nothing different from other methods. As long as the ivar used is available in the ordinary class, there is no problem at all. It's just syntactic sugar.
Things start to get more difficult if also the ivar is automatically created, as is possible in some configurations.
The main point here is that declaration of the ivar is independent from the property.