假设我有一个包含2个属性的类:
@interface MyClass ()
@property (strong, nonatomic) NSString *strA;
@property (strong, nonatomic) NSString *strB;
@end
在该类的某个地方,我有一个方法应该为这些属性中的一个赋值。问题是 - 属性将在运行时确定。我该怎么做呢?我想在没有代码复制的情况下这样做(可能是一个非常复杂的方法)。例如,这很糟糕:
- (void) mutateProperty:(BOOL)assignToA
{
if (assignToA)
{
self.strA = @"newStr";
}
else
{
self.strB = @"newStr";
}
}
我希望能够完成类似的事情:
- (void) mutateProperty:(BOOL)assignToA
{
NSString *propertyToUse = nil;
if (assignToA)
{
propertyToUse = self.strA;
}
else
{
propertyToUse = self.strB;
}
propertyToUse = @"newStr" //But this will only change the propertyToUse variable's value and not affect the scope outside the method.
}
答案 0 :(得分:2)
发布的代码不是作业,而是发送给自己的消息:
self.strA = @"newStr";
真的是
[self setStrA:@"newStr"];
(如果您为属性声明了自定义setter,方法名称可能会有所不同。)
所以你的问题是关于调度方法。有许多方法可以做到这一点,所有方法都有细节不同。然而对于你的情况,代码中只有一个点,你只选择两个选项,我会选择你已经发布的简单条件。它最易读,代码重复很少。
如果您的案例比发布的代码更复杂,您可能希望使用一些不同的派遣方式。
在Objective-C中分派的最基本方法是手动计算选择器:
SEL selector = NULL;
switch (status) {
case 1:
selector = @selector(setStrA:);
break;
case 2:
selector = @selector(setStrB:);
break;
case 3:
selector = @selector(setStrC:);
break;
}
[self performSelector:selector withObject:@"newStr"];
由于ARC无法使用选择器的名称来确定参数和返回类型所有权,因此不能与ARC一起使用。你必须使编译器警告静音,这很难看。
正如nielsbot所指出的,设置任意属性的内置方法是KVC:您可以计算KVC用来查找匹配方法的“密钥”:
NSString *key = nil;
switch (status) {
case 1:
key = @"strA";
break;
case 2:
key = @"strB";
break;
case 3:
key = @"strC";
break;
}
[self setValue:@"newStr" forKey:key];
这有点开销,但它也适用于POD参数类型。