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不是属性。如何将其转换为变量名称?或者如何在不创建无限循环的情况下设置属性?
答案 0 :(得分:0)
您可以使用object_setInstanceVariable
或object_setIvar
和object_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