I want to add a property implementation method at runtime. Add I use +resolveInstanceMethod, class_addMethod to do. But below the code, in dynamicN() and dynamicSetN(), they can’t be compiled and I don’t know how to use C-Function to set/get instance variable without synthesize property.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
float dynamicN(id self, SEL _cmd)
{
NSString *methodName = NSStringFromSelector(_cmd);
NSLog(@"%@,%@", methodName, [self description]);
// return [self n];
}
void dynamicSetN(id self, SEL _cmd, float sname)
{
printf("setName start;\n");
// self.n = sname;
}
@interface bird : NSObject
{
int height;
float n;
}
@property float n;
@property int height;
@end
@implementation bird
@synthesize height = height;
@dynamic n;
- (id)init
{
if (self = [super init]) {
n = 1.0;
height = 3;
}
return self;
}
- (float) n {
return n;
}
+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
if (aSEL == @selector(n)) {
//class_addMethod([self class], aSEL, (IMP) dynamicN, "f@:");
//return YES;
}
if (aSEL == @selector(setN:)) {
class_addMethod([self class], aSEL, (IMP) dynamicSetN, "v@:f");
return YES;
}
return [super resolveInstanceMethod:aSEL];
}
@end
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
bird *aBird = [[bird alloc] init];
aBird.n = 3;
printf("\n%f\n,%d", aBird.n, aBird.height);
[pool drain];
return 0;
}
@H2CO3 is correct about your setter. The dynamic getter has the same basic problem. You’re trying to call
[self n], which doesn’t exist onid.That’s why it won’t compile.(As @H2CO3 notes, this will generate a warning, not an error; you’re all using-Werror, right?) But more importantly, even if it did, this would be an infinite loop.self.nis just a call to[self n], which will dispatch back to this function.If you are looking for examples, you can download the code for chapter 20 of iOS 6 Programming Pushing the Limits. Look in the
Personproject forPerson.m. Chapter 28 includes a lot more explanation on how to implement this kind of feature if you’re interested.Note that proper naming in ObjC is very important. Your class should be
Bird, notbird. Getting naming basics under your belt is critical before attempting advanced features like dynamic dispatch.