Objective-C: 有没有什么技巧可以避免NSArray对象的强制转换?

4

很多时候我会将NSArray中的对象转换为我的类型,以便使用点符号(而不是getter)访问它们的特定属性,而无需创建额外的变量。

有没有一些很酷的特性或技巧可以告诉Objective-C,我要存储哪个类的对象到NSArray中,这样编译器就会假定数组中的对象是我的类型,而不是id类型?


3
你可以不使用点语法,而是使用普通的方法调用语法:[[myArray objectAtIndex:i] property](或者setProperty:...)。 - Ken Thomases
当然,我知道如何调用getter,只是我很好奇。 - ambientlight
3个回答

6

如果你所说的是以下操作:

x = ((MyClass *)[myArray objectAtIndex:2]).property1;

你可以将它分成两行,以便更容易阅读:
MyClass *myObject = [myArray objectAtIndex:2]
x = myObject.property1;

如果你坚持使用第一种情况,你可以在NSArray上创建一个类别,并为你的类型设置访问器:
@implementation NSArray (MyCategory)

- (MyClass *)myClassObjectAtIndex:(NSUInteger)index
{
   return [self objectAtIndex:index];
}

@end

然后您可以按照自己的需求使用它:
x = [myArray myClassObjectAtIndex:2].property1;

嗯 - 据我所知没有。 - Carl Norum
2
实际上是这样的。在编译时,arr[0] 被转换为 [arr objectAtIndexedSubscript:0];,因此你在分类/子类中可以通过技术手段覆盖它。但这似乎是一个可怕的想法。 - Gabriele Petronella
3
我很后悔提到那件事,所以让我尽可能清晰地说明:你不想对NSArray进行子类化。 - Gabriele Petronella
1
因为它目前运行良好,而且在子类化类簇时需要考虑一些非平凡的细节(NSArray不是一个具体的类)。阅读此文,仔细考虑是否值得为了省略几个按键而经历所有这些麻烦。 - Gabriele Petronella
1
好的,好的,我保证,我不会这样做,但是满足好奇心总是好的。 - ambientlight
显示剩余4条评论

2

在这种情况下不要使用属性。你不能说

arr[ix].myProperty

但你总可以说
[arr[ix] myProperty]

当然,我知道调用getter的方法,只是习惯使用“点”符号表示法,所以我只是就风格问题进行询问。 - ambientlight
1
风格问题在于打破点符号的习惯。或者只需继续转换... arr [ix] 是一个 id,因此您可以向其发送任何消息。但是属性不是这样工作的(因为它们被粘贴到语言中作为事后想法)。 - matt
1
是的,我总是进行强制类型转换。Smalltalk并没有考虑使用点符号表示法,因此使用较少点符号表示法是非常合理的。 - ambientlight

1

严格回答你的问题,不行。

没有语言支持来指示集合的参数类型,例如 NSArray<MyClass>

也就是说,您可以找到避免显式转换的解决方法。

由于返回的对象是 id 类型,您可以在其上调用任何现有的方法,编译器不会引起注意,除非您使用点语法符号,这种语法符号具有更严格的编译器检查。

因此,例如

NSString * name = [people[0] firstName];

无需转换即可完美运行,而
NSString * name = people[0].firstName;

doesn't.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接