簡體   English   中英

在Objective-C中在運行時確定賦值的接收者

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM