0

I'm trying to create NSString Category but the app crashes when trying to access getters/setters.

#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>

@interface NSString (MyCat)

@property (assign, nonatomic) ABRecordRef personRef;

- (void)setPersonRef:(ABRecordRef)personRef;
- (ABRecordRef)personRef;

@end

Can anyone point out the problem?

Caleb
  • 124,013
  • 19
  • 183
  • 272
jkigel
  • 1,592
  • 6
  • 28
  • 49
  • 1
    Don't thank me for your code crashing, I didn't cause that. –  Mar 09 '13 at 20:46
  • Do you have an error message to with the crash? – Mike D Mar 09 '13 at 20:47
  • Nope, merely EXC_BAD_ACCESS – jkigel Mar 09 '13 at 20:48
  • Did you implement the getter and setter? If yes, how? Note that you cannot add instance variables to a class in a category. – Martin R Mar 09 '13 at 20:52
  • 1
    Most likely the problem is (lack of) memory management with the ABRecordRef. – rmaddy Mar 09 '13 at 20:58
  • 2
    no need to declare the setter/getter in your `@interface`--those are implied by the presence of `@property`. You should show your setter/getter code. – nielsbot Mar 09 '13 at 21:07
  • 1
    Can you include an example of the usage of this property and the implementation of your getter/setter? – Hyperbole Mar 09 '13 at 21:16
  • You need to make sure that the ownership of ABRecordRef (which is a CFTypeRef) is properly handled. Overall this is a rather tedious task when dealing with categories as you will possibly be forced to store them using associated objects (runtime level). When in doubt, I would recommend rethinking your plan to wrap this kind of data using a category on NSString. – Till Mar 09 '13 at 21:33

1 Answers1

3

You cannot add properties to a class via a category. Adding methods is allowed because it doesn't increase the size of the class. Properties don't just add a getter and setter method, they also add a field to your class. The best way to add properties/fields to an existing class is to subclass it.

Lance
  • 8,872
  • 2
  • 36
  • 47
  • 2
    Properties are really just a promise to supply certain accessor methods. A property doesn't necessary imply the presence of an instance variable. AFAIK, it's quite possible to add properties in a category. – Caleb Mar 09 '13 at 22:52
  • @Caleb nope, properties also add storage for the property to the class, otherwise where would the auto-generated setter/getter store the data you are setting getting? – Lance Mar 09 '13 at 22:53
  • Caleb actually, you are right in a sense, however at some point you do have to set up a backing field for the property. Most of the time the compiler automatically calls @sythesize for you. However this will not work in this case as NSString has already been compiled into the SDK. – Lance Mar 09 '13 at 22:58
  • I just set up a little command line project to verify this. Attempting to set a property added by a category causes a crash. – Lance Mar 09 '13 at 22:59
  • 1
    That's because you didn't implement them in the category (you probably didn't implement the category), not because you can't add properties in categories. Apple added [objc_setAssociatedObject()](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/objc_setAssociatedObject) and friends in iOS 3.1 to support adding properties in categories. – tc. Mar 10 '13 at 01:50
  • @Lance There's a complete discussion in [Programming with Objective-C](http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html). It's true that you can't *just* add a property declaration and expect the compiler to fill in the blanks, but it doesn't follow that you can't use properties at all. – Caleb Mar 10 '13 at 02:04
  • @Caleb and tc, I stand corrected! I learned something new today. Thanks :) However, this is probably what the asker is trying to do. _just_ add the properties. That's all we can infer from the code he provided. – Lance Mar 10 '13 at 03:13