【问题标题】:iOS - How to access object properties in an array properly?iOS - 如何正确访问数组中的对象属性?
【发布时间】:2012-08-11 18:23:39
【问题描述】:

设置:

ViewController 拥有来自PersonClass 的对象的MyArrayPersonClass 只有两个属性:nameage

问题:

当我想从MyArray 中的第一个对象中读取name 属性时,正确的方法是什么?

我必须像这样临时创建PersonClass 的实例吗?

PersonClass *tmp = [PersonClass alloc] init];
tmp = [MyArray objectAtIndex:0];

NSLog(@"%@", tmp.name);

或者我可以直接参考MyArrayobjectsproperties吗?

类似这样的:

 NSLog(@"%@", [self.contactsArray objectAtIndex:0].name); // not working

【问题讨论】:

    标签: iphone ios properties nsarray ivar


    【解决方案1】:

    如果您想要或需要该类型,请像这样引入该类型:

    PersonClass * person = [array objectAtIndex:0];
    

    为了可读性,我经常这样做,因为包含文件的声明否则会破坏事情。

    请注意,当从 id 值分配 objc 变量时,不需要进行 强制转换

    我必须临时创建一个 PersonClass 的实例吗?

    没有。您编写的程序会创建一个从未使用过的临时文件。

    【讨论】:

    • not required when assigning a variable... 来自返回类型为id的方法
    • @Paul.s 好吧 - 我会补充的。我认为上下文定义明确。
    【解决方案2】:

    我强烈建议使用

    [(PersonClass *)[MyArray objectAtIndex:0] name]
    

    而不是看似干净,但麻烦的形式

    [[MyArray objectAtIndex:0] name]
    

    这有两个原因。首先,对于读者来说,在哪个对象上调用了什么是明确的。其次,它对编译器是显式的 - 如果两个方法共享相同的名称,但返回值不同,事情就会变得很糟糕。 Cocoa With Love 的 Matt Gallagher 有一个excellent explanation of this issue.

    【讨论】:

      【解决方案3】:

      我必须像这样临时创建一个 PersonClass 的实例吗?

      PersonClass *tmp = [PersonClass alloc] init];
      tmp = [MyArray objectAtIndex:0];
      
      NSLog(@"%@", tmp.name);
      

      没有。只需使用

      PersonClass *tmp = (PersonClass *)[myArray objectAtIndex:0];
      NSLog(@"%@", tmp.name);
      

      由于您从 myArray 获取的对象是(或应该是!)在添加到数组之前已经分配和初始化。数组中的事物是指向对象的指针。这就是你正在传递的东西。你必须告诉它你有哪种类型的对象(演员是(PersonClass *)),因为 NSArray 只存储 NSObjects。

      你也可以这样在一行中完成

      ((PersonClass *)[myArray objectAtIndex:0]).name;

      【讨论】:

      • 这里的演员PersonClass *tmp = (PersonClass *)[myArray objectAtIndex:0]; 完全是多余的。只是想我会提到你特别注意解释你为什么这样做......
      • @Paul.s 很好。最近在做 Java 太多了!
      【解决方案4】:
      ((PersonClass *)[MyArray objectAtIndex:0]).name
      

      或者只是[[MyArray objectAtIndex:0] name]

      【讨论】:

      • “或者只是”是杀手;)谢谢。
      • 这里最好使用第二个例子——这不是强制转换——特别是如果你调用的是方法而不是属性。问题是编译器必须猜测选择器的参数类型。当两个同名的选择器具有不同的类型时,它可能会出错。更多详情请见cocoawithlove.com/2011/06/…
      【解决方案5】:

      你可以这样做

      PersonClass *tmp = (PersonClass *) [MyArray objectAtIndex:0];
      NSLog(@"%@",tmp.name);
      

      或者我们可以把它放在一行上:

      NSLog(@"%@",((PersonClass *)[MyArray objectatIndex:0]).name);
      

      NSLog(@"%@", [self.contactsArray objectAtIndex:0].name); 不起作用的原因是你没有告诉编译器[self.contactsArray objectAtIndex:0] 是什么类型的对象。因为它不知道你的数组中有什么类型的对象,所以它没有办法知道它有一个name 属性

      【讨论】:

      • 我想把它做成一个单行,但为什么要降低可读性呢? [[self.contactsArray objectAtIndex:0] name] 更容易阅读
      猜你喜欢
      • 2016-02-26
      • 1970-01-01
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多