2012-01-10 80 views
4

我想在运行时添加一个属性实现方法。添加我使用+ resolveInstanceMethod,class_addMethod来做。但在代码下面,在dynamicN()和dynamicSetN()中,它们不能被编译,我不知道如何使用C函数来设置/获取实例变量而不合成属性。如何生成动态属性getter/setter?

#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, "[email protected]:"); 
     //return YES; 
    } 
    if (aSEL == @selector(setN:)) { 
     class_addMethod([self class], aSEL, (IMP) dynamicSetN, "[email protected]: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; 
} 
+0

请添加您从编译器获得的错误消息。 – 2012-01-10 18:51:42

回答

2

@ H2CO3对于您的二传手是正确的。动态吸气器具有相同的基本问题。您正尝试拨打[self n],这在id上不存在。 这就是为什么它不会编译。 (As @ H2CO3注意到,这会产生一个警告,而不是一个错误;你们都使用-Werror,对吧?)但更重要的是,即使这样做,这将是一个无限循环。 self.n只是致电[self n],它将发回此功能。

如果您正在寻找示例,您可以下载iOS 6 Programming Pushing the Limits的第20章的代码。查看Person项目Person.m。如果你感兴趣的话,第28章会详细解释如何实现这种功能。

请注意,在ObjC中正确命名非常重要。你的班级应该是Bird,而不是bird。在尝试诸如动态分发之类的高级功能之前,获取命名基础知识至关重要。

2

您的二传手不能编译,因为你的self参数的类型是“ID”,这本身没有名为“n”的财产。你要投那么直接取消对它的引用:

((bird *)self)->n = sname; 

你消气似乎不错,虽然,我不知道为什么它不能被编译。

+0

getter自己调用并且在运行时不起作用。需要进行与setter相同的字段访问才能获得返回值。不过,我看不出为什么它不能编译。 – 2012-01-10 18:51:23

+0

类型“id”在语法上没有名为“n”的属性。编译器不知道它实际上是否响应-n或-setN:方法(这是动态的价格) – 2012-01-10 19:57:53

+0

是否意味着(id)-dynamic类型绑定的使用与C函数中的静态类型不同? objective-c方法中静态类型和动态类型之间是否存在一些差异? – 2012-01-11 07:19:06

相关问题