【发布时间】:2013-04-25 13:52:10
【问题描述】:
大家好,
我一直在研究 Objective-C 中执行对象自省的一些枚举例程。特别是,在调整它们的属性和/或调用它们的方法之前,我正在快速枚举 NSSet 并确保其中的对象属于 BBBallView 类(我同意这是一个相当不幸的名称)。
然而,为了让解析器和编译器满意,我最终在每一行都将对象转换为它的类;此外,为了访问其属性,对象的强制转换必须在括号中,否则点符号将不起作用。这会导致代码有些混乱:
for (id otherBall in self.gameField.subviews) {
if ([otherBall isKindOfClass:[BBBallView class]]) {
if ( !((BBBallView *)otherBall).isEnlarged ) {
CGRect otherFrame = ((BBBallView *)otherBall).frame;
/* ... */
}
}
}
有没有办法告诉编译器“此时我知道otherBall 是BBBallView,所以不要再告诉我它不响应这些选择器和属性”?这样一来,你就可以写:
for (id otherBall in self.gameField.subviews) {
if ([otherBall isKindOfClass:[BBBallView class]]) {
if ( !otherBall.isEnlarged ) {
CGRect otherFrame = otherBall.frame;
/* ... */
}
}
}
等等。
我尝试了otherBall = (BBBallView *)otherBall,但“默认情况下无法在 ARC 中修改快速枚举变量”。将枚举变量更改为__strong id 可以修复它,但无济于事,因为任何后续行都会给出错误,例如“在'const __strong id'类型的对象上找不到属性isEnlarged”,所以我回来了平方一。
我什至不确定为什么会发生这种情况:当变量的类型为id 时,编译器不应该置身事外吗?无论如何,在需要对对象的属性执行多次计算的方法中,整个考验尤其混乱,因为所有这些括号很快就会变得不可读。
有没有办法解决这个问题?
提前致谢!
【问题讨论】:
-
一般来说,重度内省模式是一种代码味道。集合通常不应包含异构类型。此外,拥有一个提供基本服务的抽象类,以及细化行为的特定子类,可以避免大量的自省。
标签: objective-c casting enumeration introspection