[英]Determining the receiver of an assignment at runtime in Objective-C
假設我有一個包含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.
}
發布的代碼不是作業,它發送給自己的消息:
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參數類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.