【问题标题】:How can I access a property with a string inside of dot notation?如何使用点符号内的字符串访问属性?
【发布时间】:2013-01-23 15:14:00
【问题描述】:

查看以下代码:

@property (weak, nonatomic) UILabel *l112;
@property (weak, nonatomic) UILabel *l212:
@property (weak, nonatomic) UILabel *l312:

((RBScorecardVC *)self.presentingViewController).l112.text = @"Hello"
((RBScorecardVC *)self.presentingViewController).l212.text = @"Hello"
((RBScorecardVC *)self.presentingViewController).l312.text = @"Hello"

请注意我如何将标签的所有文本设置为“Hello”。必须有一种更有效的方法来做到这一点。我希望我能以某种方式访问​​ UIlabels 的名称(l112、1212 等)来做到这一点。这有意义吗?在我的实际应用程序中,我并没有真正将所有内容都设置为“Hello”,而是文本是计算的结果。此外,在我的实际应用程序中,我要设置超过 3 个标签(有 50 多个)这是我的实际代码,它使用重复的 if 语句单独访问每个 UILabel:

-(IBAction) submitScore: (id)sender
{
self.stringID = ((RBScorecardVC *)self.presentingViewController).self.giveString;

if (self.stringID isEqualToString:@"l112")
{ ((RBScorecardVC *)self.presentingViewController).l112.text = [[NSString alloc]initWithFormat:@"%d", self.accumulator];} //l112 is the name of my UILabel
else if (self.stringID is EqualToString:@"l212")
{ ((RBScorecardVC *)self.presentingViewController).l212.text = [[NSString alloc]initWithFormat:@"%d", self.accumulator];} //l212 is the name of my UILabel
}

我希望能够像这样更有效地做到这一点:

-(IBAction) submitScore: (id)sender
 self.stringID = ((RBScorecardVC *)self.presentingViewController).self.giveString;

 ((RBScorecardVC *)self.presentingViewController).[UILabel withTitle:@"%@",stringID].text = [[NSString alloc]initWithFormat:@"%d", self.accumulator];}

注意我的 [UILabel withTitle: @"%@", stringID] 部分在点表示法中使用。我知道这不起作用,但我想知道如何正确编写它,以便可以使用 stringID 访问我需要的 UILabel 的名称?

【问题讨论】:

  • + [UILabel withTitle:] 是什么?
  • 您应该使用 NSArray,并有一个使用该数组的搜索方法。 UI 元素的 NSArray 可以使用 IBOutletCollection从 XIB 设置

标签: ios objective-c syntax properties


【解决方案1】:

尝试在您的 UILabel 上使用 valueForKey:

但是,更简洁的解决方案可能是将这些属性简单地存储在 NSDictionary 中。

【讨论】:

    【解决方案2】:

    这里的其他答案涉及对象的属性。在这种情况下,您尝试访问对象本身。当您开始问自己这样的问题时,您应该只将所有对象(在本例中为标签)存储在数组属性中,而不是每个标签的单独属性中。与其将标签视为l112 之类的命名变量,不如将它们视为数组中的索引:

    UILabel *theLabelINeed = [self.myArray objectAtIndex:2]; [theLabelINeed callWhateverMethodINeedTo];

    或者更短,如果你来自 python/ruby 背景并且这对你来说更具可读性:

    [self.myArray[2] callWhateverMethodINeedTo];

    如果需要快速访问数组中的每个标签,可以在 for 循环中使用快速枚举:

    for (UILabel *currLabel in self.myArray) {
        [currLabel callWhateverMethodINeedTo];
    }
    

    您也可以改用NSDictionary,它允许您为对象分配“键”或名称。

    NSDictionary *dict {"l112": label1, "l113": label2}; // or some other dictionary creation method, maybe a mutable dictionary or whatever.
    UILabel *myLabel = [dict objectForKey:@"l112"];
    

    【讨论】:

    • 我喜欢数组的想法。我可以这样做吗:[myLabelArray objectAtIndex:i].text = @"无论我需要我的文本是什么";如果我在数组中的所有对象都是 UILabel,并且 UILabel 有一个 text 属性,我可以访问该属性,如图所示?
    • 当然!在您的脑海中,您可以将所有括号评估为它们返回的内容。所以objectAtIndex: 返回一个UILabel,然后在返回的UILabel 实例上调用setText:。如果您最终使用我的答案,请不要忘记将其标记为正确:)
    • 我会尝试一下,看看这是否值得打勾! NSDictionary 选项看起来也很性感。谢谢!
    • 仅供参考:我使用了数组方法,它就像魅力一样。谢谢!我不能使用括号中的 dict 等效项的 [myLabelArray objectAtIndex:i].text 或 .text 属性。它说在对象 ID 上找不到文本属性。我最终需要设置我的数组的一个实例并在我的代码中引用它,例如 myLabelArrayIntance.text
    • 感谢您告诉我!是的,我后来意识到你必须转换它并且你不能使用点符号来做到这一点:[(UILabel *)[arr objectAtIndex:5] setText:@"myText"]
    【解决方案3】:

    您为什么要使用点表示法 - 最初用于对象 @properties - 用于其他用途?

    Dot Notation vs Method Notation

    您似乎对 Objective-C 语法感到困惑:为什么 [UILabel withTitle:"%@", stringId] 而不是更简单的 [UILabel withTitle:stringID],或者如果 stringId 不是字符串,[UILabel withTitle:[NSString stringWithFormat:@"%@", stringID]]

    另外,为什么 withTitleUILabel 的类方法而不是 presentingViewController 的实例方法?

    【讨论】:

    • ((RBScorecardVC *)self.presentingViewController)
    • 是的,所以? RBSscorecardVC 很可能有一个 - (UILabel*)labelWithTitle: 实例方法,不是吗?
    【解决方案4】:

    这样的事情可能会满足您的要求,但我同意使用 NSDictionary 的答案可能更易于维护。或者,您可以在 IB 中的标签上使用整数标签属性并调用父视图的 viewWithTag: 方法。

    - (UILabel *)labelWithName:(NSString *)name
    {
        SEL selector = NSSelectorFromString(name);
        if (![self respondsToSelector:selector])
            return nil;
    
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        id result = [self performSelector:selector];
    #pragma clang diagnostic pop
        if (!result)
            return nil;
        if (![result isKindOfClass:[UILabel class]])
            return nil;
        return (UILabel *)result;
    }
    
    - (IBAction)derp:(id)sender
    {
        UILabel *label = [self labelWithName:@"label1"];
        [label setText:@"I'm label 1"];
        label = [self labelWithName:@"label2"];
        [label setText:@"I'm label 2"];
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      相关资源
      最近更新 更多