大家好,
我一直在Objective-C中处理一些执行对象内省的枚举例程。特别是,在调整属性和/或调用方法之前,我正在快速枚举NSSet
并确保其中的对象属于类BBBallView
(一个相当不幸的名称,我同意)。 / p>
然而,为了使解析器和编译器满意,我最终将对象转换为每一行的类;此外,为了访问其属性,对象的强制转换必须在括号中,否则点符号将不起作用。这导致代码有些混乱:
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 isEnlarged
在类型为'const __strong id'”的对象上找不到的错误,所以我回到原点。
我甚至不确定为什么会发生这种情况:当变量属于id
类型时,编译器是否应该避开?在任何情况下,对于需要对对象属性执行多次计算的方法,整个考验特别麻烦,因为所有这些括号很快就会变得不可读。
有什么方法吗?
提前致谢!
答案 0 :(得分:4)
您可以使用正确的类型创建本地temp,也可以不使用点表示法。
本地临时
for (UIView *view in self.gameField.subviews) {
if ([view isKindOfClass:[BBBallView class]]) {
BBBallView *ballView = view;
if (!ballView.isEnlarged) {
CGRect otherFrame = ballView.frame;
/* ... */
}
}
}
不要使用点符号
for (id otherBall in self.gameField.subviews) {
if ([otherBall isKindOfClass:[BBBallView class]]) {
if ( ![otherBall isEnlarged]) {
CGRect otherFrame = [otherBall frame];
/* ... */
}
}
}
如果我只做了几件事,我很想不使用点符号。如果它变得难以阅读并且有很多访问,那么我会考虑本地临时
答案 1 :(得分:1)
我认为你正在努力,因为逻辑似乎错位了。由于你的程序结构,语言正在打击你,而不是因为语言不足。
子视图的父类型是否真的合适?或者你是否通过在方形类型中填充圆形物体来违反Liskov替换原则?
您还可以询问从外部检查BBBallView逻辑的内部是否真的合适?你能把逻辑移到适当的班级吗?