动态创建@dynamic属性的getter和setter,导致无限循环

时间:2013-12-11 17:30:30

标签: c++ objective-c

Currenlty我有一个ocmock用于单元测试的问题,因为一些@dynamic属性在被模拟时没有getter或setter。我正在使用class_addmethod为所有@dynamic属性添加getter和setter。我的问题是这个

void accessorSetter(id self, SEL _cmd, id newValue)
{
    NSString *method = NSStringFromSelector(_cmd);
    id value = [newValue copy];
// remove set prefix from string
    NSString *anID = [[method stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""] stringByReplacingOccurrencesOfString:@":" withString:@""];
    anID = [anID stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[anID substringWithRange:NSMakeRange(0, 1)] lowercaseString]];
    [self setValue:value forKey:anID];
}
由于setValue调用setter,

会导致infite循环。我想我可以使用像self->somevar = value这样的c ++语法来避免无限循环。我的问题是,当变量的名称是字符串时,如何进行此分配? anID是变量的名称,我不能self->anID = aValue cuz anID不是属性。如何将其转换为变量名称?或者如何在不创建无限循环的情况下设置属性?

1 个答案:

答案 0 :(得分:0)

您可以使用object_setInstanceVariableobject_setIvarobject_getInstanceVariable。您可以查看Objective C Runtime Reference以获取更多信息。

修改 如果您使用ARC,则无法使用object_setInstanceVariable。你会被object_setIvar困住。

编辑2:如果您使用的是ARC,请参阅this

使用示例:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface Test : NSObject
@property (nonatomic, strong) NSString *test;
@end
@implementation Test
- (id)init {
    if (self = [super init]) {
    self.test = @"asdasd";
    }
    return self;
}
- (void)setTest:(NSString*)test {
    Ivar var_desc = object_getInstanceVariable(self, [@"_test" cStringUsingEncoding:NSUTF8StringEncoding], NULL);
    NSLog(@"Setting _test to %@", test);
    object_setIvar(self, var_desc, test);
}
@end

int main(int argc, char *argv[])
{
    Test *tst = [[Test alloc] init];
    NSLog(@"prop: %@", tst.test);
    return 0;
}

输出:

2013-12-11 18:19:32.038 ivar_tst[97090:507] Setting _test to asdasd
2013-12-11 18:19:32.040 ivar_tst[97090:507] prop: asdasd