0

This question might not be so practical. It's pure curiosity.

Why category in ObjC can't add properties to existing class?

"To add properties to existing class you should use associative reference" kind of answer is not appreciated.

Thanks

EDIT

After reading answers I understand now that it's not true about category can't add properties or more precisely using properties in category. I've tried to declare property in category with custom setter and getter in category implementation. It works fine.

So @jlehr is right this is a duplicate of question Why can't categories have instance variables? and there is a great answer about why

Community
  • 1
  • 1
dopcn
  • 4,218
  • 3
  • 23
  • 32
  • Property has type (class) so you can use categories methods... – Injectios May 23 '14 at 14:26
  • 2
    You can add `properties` to a class category. However you can't synthesize them so the getters/setters will not be automatically generated for you, you have to use `@dynamic` and implement the getters/setters yourself and use associative references. – Popeye May 23 '14 at 14:35
  • 1
    Why are people voting to close as being primarily opinion based? The answer is not opinion based. There is a definite technical reason why. – rmaddy May 23 '14 at 15:02
  • possible duplicate of [Why can't categories have instance variables?](http://stackoverflow.com/questions/21035660/why-cant-categories-have-instance-variables) – jlehr May 23 '14 at 15:14
  • 2
    It was a specific design decision. Categories are already abused more often than they are actually used; categories on system classes are nightmare of binary compatibility issues and a source of crashes. Adding ivar like storage into categories would have made this problem significantly worse. – bbum May 23 '14 at 16:23
  • possible duplicate of [Properties in categories](http://stackoverflow.com/q/21900826) – jscs May 23 '14 at 18:58

3 Answers3

4

Categories can be loaded at runtime. When that happens, the methods they implement are added to classes dynamically. If categories were modified to allow adding instance variables as well, objects that were instantiated before a category was loaded might not be large enough to accommodate the new instance variables.

jlehr
  • 15,557
  • 5
  • 43
  • 45
2

You can add properties to a category. What you can't add is instance variables for those category properties.

You can create a category with an @property declaration and then provide your own custom setter and getter for the property. This all works fine.

Perhaps a better question is "why can't you add instance variables in a category". In that case, see Why can't categories have instance variables?

Community
  • 1
  • 1
rmaddy
  • 314,917
  • 42
  • 532
  • 579
1

Property usually is an ivar with getter and setter methods. You can add those methods to an existing class but you can't add an ivar. There is Obj-C runtime function class_addIvar that can add an ivar but it doesn't work for existing classes as stated in the documentation

This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.

That's why people suggesting associative reference. That way you can only fake an ivar. Why - inside Obj-C classes are just a C structures. Registered classes already has that C structure defined and it can't be changed afterwards for obvious reasons. That's just how the language works.

Popeye
  • 11,839
  • 9
  • 58
  • 91
creker
  • 9,400
  • 1
  • 30
  • 47