Chipmunk碰撞回调短时间内重入的解决办法

Chipmunk引擎中碰撞行为可能在细微处与一般认识略有不同.

比如碰撞回调方法可能会重入.不知道方法(函数)重入概念的童鞋可以自行谷哥或度娘.

第一次碰撞方法还未返回,第二次碰撞回调又被调用了.至于它们是否运行在同一线程,这个不知道.至少我调试中都在一个线程里.但在一个线程里也会发生重入.这里研究的不深入,有错误请指出.

最开始碰撞回调方法如下:

-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair star:(CCNode *)star
                         stick:(CCNode *)stick{
    StarType starType;
    if (!star) {
         return YES;
    }

     starType = ((Star*)star).starType;
     star = nil;
    }

    //working

    [star removeFromParentAndCleanup:YES];
    return YES;
}

以上代码中的working短时间内偶尔会执行2次.第1次修改将star removeFromParentAndCleanup调用移至方法前部也不行.

第2次修改如下:

@synchronized(self){
        if (!star) {
            return YES;
        }

        starType = ((Star*)star).starType;
        [star removeFromParentAndCleanup:YES];
        star = nil;
    }
    //working...

任然不行,从日志上看star调用remove方法后其值仍有可能不为nil,导致if判断失败.

第3次修改增加了if判断条件为:

if (!star || !star.parent) {
      return YES;
}

代码逻辑工作正常,在第二次重入时,star.parent一定为(还是不能肯定,说”应该为”比较妥当 ;)nil,所以避免了再次调用working逻辑.

可能我代码逻辑也有问题,不能依赖于方法的重入次数.因为有了物理引擎回调这个不确定因素,所以使得问题发生的很显然.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-20 05:12:23

Chipmunk碰撞回调短时间内重入的解决办法的相关文章

【转】自定义UITableViewCell控件阻挡回调不到didSelectRowAtIndexPath的解决办法

原文网址:http://blog.talisk.cn/blog/2015/09/01/uitableview-didselectrowatindexpath-cannot-be-called-tips/ 作为常用的控件,UITableView出现在了很多iOS App的各个地方,近期开发时遇到了一个问题,自定义Cell中嵌套了其他具有交互事件的控件,阻挡了Cell,导致无法回调didSelectRowAtIndexPath方法,最终得出解决办法. 一句话方案 将可能影响到Tap事件的控件的use

java 实现多个接口 方法重名的解决办法——内部类

package com.kk.innerClass; /** * 通过内部类实现接口 * 解决多个接口中方法重名问题 * */interface Machine { void run();} class Person { void run() { System.out.println("person start"); }} public class Android extends Person { private class MachineHeart implements Machin

关于suse系统忘记密码后,无法登入的解决办法

1.重新启动机器,在出现grub引导界面后,在启动linux的选项里加上init=/bin/bash,通过给内核传递init=/bin/bash参数使得OS在运行login程序之前运行bash,出现命令行. 2.稍等片刻出现(none)#:命令行. 3.这时输入mount -n / -o remount,rw 表示将根文件系统重新mount为可读写,有了读写权限后就可以通过passwd命令修改密码了. 4.这时输入passwd命令就可以重置密码了.输入一个你记得住的密码,不过记不住也无所谓,现在

.NET的内建定时器类型是否会发生回调方法冲入

分析问题 所谓的方法重入,是一个有关多线程编程的概念.程序中多个线程同时运行时,就可能发生同一个方法被多个线程同时调用的情况.当这个方法中存在一些非线程安全的代码时,方法重入就会导致数据不一致的情况,这是非常严重的Bug. 在前文中,笔者已经简要介绍了.NET的内建定时器类型,它们是: 1.System.Windows.Forms.Timer. 2.System.Threading.Timer. 3.System.Timers.Timer. 这三种类型的计时方法是不同的,这里笔者分别分析了三种类

不可重入定时器Newlife.TimerX

在.net常用的定时器类有下面三种,使用定时器时需要设定参数,如间断时间.定时器计溢出后的回调函数.延时.开始等,定时器的的主要方法有开始.终止等,不同的定时器实现上述的方法会有一些差异,本文会针对具体的定时器一一举例说明. 1.System.Windows.Forms.Timer类 2.System.Threading.Timer类 3.System.Timers.Timer类 一.System.Windows.Forms.Timer 从这个定时器的命名空间可以看出,.net设计这个定时器的目

线程安全与可重入函数的联系与区别

轻量级进程(LWP)是计算机操作系统中一种实现多任务的方法. 在计算机操作系统中,轻量级进程(LWP)是一种实现多任务的方法.与普通进程相比,LWP与其他进程共享所有(或大部分)它的逻辑地址空间和系统资源:与线程相比,LWP有它自己的进程标识符,优先级,状态,以及栈和局部存储区,并和其他进程有着父子关系:这是和类Unix操作系统的系统调用vfork()生成的进程一样的.另外,线程既可由应用程序管理,又可由内核管理,而LWP只能由内核管理并像普通进程一样被调度.Linux内核是支持LWP的典型例子

聊聊高并发(十六)实现一个简单的可重入锁

可重入锁指的是如果一个线程已经获得了一个锁,那么它可以多次进入这个锁,当然前提是线程需要先获得这个锁. 可重入锁是最常使用的锁,Java的内置锁就是可重入锁,使用synchronized关键字可以启用内置锁机制,比如说一个类有两个synchronized方法A和B,在A方法中调用了B方法,如果锁不是可重入的,那么访问B时需要再次竞争锁,这样会带来死锁. public synchronized void A(){ B(); } public synchronized void B(){ } 可重入

Java多线程可重入锁例子解析

"可重入锁"的概念是:自己可以再次获得自己的内部锁.比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁. class sysTest{ synchronized void test1(String str){ System.out.println(str+"1"); test2(str); System.out.println("end" + str); }

Signal处理中的函数可重入问题

1. Signal信号简介 信号是软件层次上模拟的中断,它是一种异步通信的处理机制.信号的异步性意味着,应用程序不用等待事件的发生,当信号发生时应用程序自动陷入到对应的信号处理函数中.产生信号的事件对进程而言是随机出现的.信号的响应方式有忽略.捕捉.执行默认动作三种. 2. 线程安全 线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其他共享资源的函数都是线程安全的.使用全局变量的函数是非线程安全的.使用静态数据或其他共享资源的函数,必须通过加锁的方式来使函数实现线程安全. 线