我遇到了军队可以攻击建筑物的情况。每支部队都有一个指向其目标的指针。
@property (nonatomic, weak) Building *target;在更新循环中,部队会周期性地对目标造成伤害。
if (_target)
{
if (/*enough time has passed since last attack, attack again*/)
{
[_target attack];
if (_target.health <= 0)
{
[_target removeFromParentAndCleanup:YES]; //Cocos2d
_target = nil;
}
}
}
else /* Find new target */ 问题是:
troop1给了building1一个打击,然后转移到了building2troop2攻击building1,但直到下一次攻击才确定building1现在是nil。我意识到问题在于,troop2的指针没有被设置为零,相反,我应该检查指针的值是否为零。
我试过使用if (*_target),但是遇到了这个消息
语句需要标量类型的表达式。
在目标C中是否有实现这种比较的方法?还有哪些其他选项可用于确定值何时发生了更改?KVO?一些广泛的委托模式?
发布于 2013-02-20 16:08:02
当指针所指向的对象被解除分配时,指针本身被设置为零。if (objectPointer == nil)总是用来检查对象在目标中是否为零的方式--C/Cocoa。如果指针不是零,它意味着所讨论的对象实际上还没有被释放。如果取消引用指向对象的指针,则会得到一个结构,因此编译器在If表达式中需要标量值时出错。
因此,在您的示例中,如果if(self.target != nil)没有给出您期望的结果,那么您应该查找(来自其他对象)对目标的强引用。
更广泛地说,正如trojanfoe的回答所暗示的那样,您正依赖ARC对弱引用行为进行归零以获得真正的程序逻辑。理论上,这是可以的,因为(与他最初的陈述相反),ARC的零位弱行为是可靠的/确定性的。但是,这确实意味着,当目标不再在比赛场地上(或其他什么)时,你必须确保目标总是被取消。这有点易碎。将弱引用归零是为了避免保留周期(本质上是内存泄漏的一种形式),而不是以您正在做的方式实现逻辑。trojanfoe解决方案的要点是,在必要时显式注册和注销目标,这可能是一个更健壮的解决方案。
发布于 2013-02-20 15:44:17
我在这里可能忽略了一些东西,但是要检查target2属性是否为nil,只需:
if ( self.target2 == nil ) {
// Something
}发布于 2013-02-20 16:09:17
因为target是弱引用,所以您的代码应该“按原样”工作,假设[_target removeFromParentAndCleanup:YES];删除了对目标的所有强引用。
当删除最后一个强引用时,指向它的所有弱属性将自动设置为nil。如果它们没有自动设置为nil,那么仍然有对目标的强烈引用。
找到并删除该引用,这将很好。
https://stackoverflow.com/questions/14983670
复制相似问题