Reputation: 40211
I'm trying to add an instance variable and a property to an existing class. I want to do this to extend the base class of an open source library, without modifying the source code (for easier code management).
The documentation says
Unlike regular categories, a class extension can add its own properties and instance variables to a class. If you declare a property in a class extension [...] the compiler will automatically synthesize the relevant accessor methods, as well as an instance variable, inside the primary class implementation.
I tried to do this in a test app. I have an empty class ClassA
:
ClassA.h
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@end
ClassA.m
#import "ClassA.h"
@implementation ClassA
@end
Then I added an extension:
ClassA+Ext.h
#import "ClassA.h"
@interface ClassA ()
@property (nonatomic) NSString *name; // <-- this is my new property
@end
Finally in my AppDelegate
I simply init a ClassA
and try to set and then log the name
.
#import "AppDelegate.h"
#import "ClassA.h"
#import "ClassA+Ext.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
ClassA *a = [[ClassA alloc] init];
a.name = @"test";
NSLog(@"Name: %@", a.name);
}
@end
This compiles and runs, but I get this error on the console:
2013-05-10 00:58:08.598 Test[53161:303] -[ClassA setName:]: unrecognized selector
sent to instance 0x108a1a630
2013-05-10 00:58:08.600 Test[53161:303] -[ClassA setName:]: unrecognized selector
sent to instance 0x108a1a630
The name is not logged. And if I set a breakpoint and inspect the ClassA
instance, it doesn't have a name
ivar. What am I doing wrong? Isn't this actually possible to do?
Upvotes: 1
Views: 1202
Reputation: 1740
Your understanding is incorrect. You added a property through a class extension. This property should only be able to be used inside your class. It should not be used as a true "property" for your class in which you can change it through external instantiation. Think of it as a pseudo private instance variable.
I believe what you want to do is simply subclass your Class A.
Another viable solution proposed was:
"You can write a category to wrap it into -[setAssociatedObject:forKey:]" when using objc_setAssociatedObject --> by @Artur
Upvotes: 3
Reputation: 896
I think class extensions are meant to be put in the class.m files, usually above the @implementation of the class.
Upvotes: 0