tags:

views:

101

answers:

3

Obj-C 2.0 lets me declare properties in a category, but the compiler refuses to synthesize accessors inside the category. Why?

(Sometimes it makes organization sense to put a bunch of related stuff in a category - even if the backing iVars go in the class declaration. I know about class extensions and how to do private properties, but that isn't my use case.)

A: 

A very similar question has been asked here.

Nick Stamas
A: 

The question asked there covers the private accessor problem. This approaches from a non-private-accessor POV.

+1  A: 

The issue is that categories are logically separate from their classes, and are even stored separately in the binary file. The internal implementation is that a class description structure holds an array of method lists which initially contains only the list of methods defined in the main @implementation block. As the ObjC linker modules load new categories, their method lists are added to that array.

Because of this implementation, the categories themselves have no means of accessing the storage for a class, and therefore cannot modify it (it also opens up the question of what to do when the category is un-loaded).

Lastly, from a more logical rather than technical perspective, the idea is that a category doesn't have any 'ownership' of the in-memory structure of a class, it simply associates some new methods. To fully support property synthesis, it would need to modify the class's storage in some way

The solution? You either put the @synthesize statements inside your main @implementation block, or you just implement your own accessors directly within the category @implementation.

Jim Dovey
Let me be more specific. I've broken out some methods into a category for organizational purposes, and since I own the class, I added appropriate iVars to the classes interface. But I still can't @synthesize the methods in the category.Is there a technical reason why not? I still don't see one.
That doesn't really make a great deal of difference. The fact that you're the author of both the class and the category isn't encoded by the runtime in any way, so the category is still just a separate entity with no connection to the storage specifiers of the class which it references. Like I said, it's sort of a 'protection' mechanism-- you just have to @synthesize the variables inside the main @implementation block for the class (that works fine for me).
Jim Dovey