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-29 03:08:53

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

开机提示网络上有重名的解决方法

笔者记得前段时间单位里新买了一批电脑,刚安装完,逐渐有同事来问各种问题,比方说今天这个:右下角弹出窗口,提示"网络上有重名",上网断断续续的,怎么办?这是大批量装机的后遗症,改一下计算机名字就好了. 网络上有重名 网络上有重名的解决办法: 解决网络上有重名提示的办法就是修改计算机名字,具体步骤是: 在桌面"我的电脑"上右键单击,选择"属性",在弹出窗口中寻找"计算机名"标签,点击后在计算机名页面下面点击"更改&quo

python中threading之死锁和可重入锁

一.死锁 简单来说,死锁是一个资源被多次调用,而多次调用方都未能释放该资源就会造成死锁,这里结合例子说明下两种常见的死锁情况. 1.迭代死锁 该情况是一个线程"迭代"请求同一个资源,直接就会造成死锁: import threading import time class MyThread(threading.Thread):     def run(self):         global num         time.sleep(1)         if mutex.acqu

安装MYSQL-PYTHON包报错mysql_config not found解决办法

使用pip install MySQL-python的方式安装,遇到以下几个问题: 1.提示错误EnvironmentError: mysql_config not found 这是因为本机是Mac OSX系统,并且装的MySQL是MAMP集成环境中的,实际上mysql_config这个文件是存在的,但是默认包里面的路径有问题,可以重新装一个MySQL到系统默认位置,不过既然已经有了MySQL不想重复装. 解决办法是从pypi官网下载一个MySQL-python包,然后修改其中的setup_po

java 可重入读写锁 ReentrantReadWriteLock 详解

读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作.只要没有writer,读取锁可以由多个reader线程同时保持.写入锁是独占的.互斥锁一次只允许一个线程访问共享数据,哪怕进行的是只读操作:读写锁允许对共享数据进行更高级别的并发访问:对于写操作,一次只有一个线程(write线程)可以修改共享数据,对于读操作,允许任意数量的线程同时进行读取.与互斥锁相比,使用读写锁能否提升性能则取决于读写操作期间读取数据相对于修改数据的频率,以及数据的争用--即在同一

什么是可重入函数

什么叫可重入: 可重入是一个并发下才有的概念.如果说,程序是串行的,自然也就不会有可重入这回事了.因为并发,所以任何个步骤都可能在运行中途被中断,然后跑另一个代码.这样就会出现一种可能,比如说两段代码都操作了一个全局变量,就会造成意想不到的错误. 可重入函数指的是,有多个线程在并发的执行一个函数.这个时候,如果两个函数会操作同一个全局的变量.这就是上面说的场景了. 什么样的函数不可重入: 函数体内使用了静态的数据结构(全局变量等). 函数体内调用了malloc()或者free()函数. 函数体内

JUC 可重入 读写锁 ReentrantReadWriteLock

本文首先发表在 码蜂笔记 读写锁 ReadWriteLock 读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作.只要没有writer,读取锁可以由多个reader线程同时保持.写入锁是独占的. 互斥锁一次只允许一个线程访问共享数据,哪怕进行的是只读操作:读写锁允许对共享数据进行更高级别的并发访问:对于写操作,一次只有一个线程(write线程)可以修改共享数据,对于读操作,允许任意数量的线程同时进行读取. 与互斥锁相比,使用读写锁能否提升性能则取决于读写操作期间读取数据相对于修改数据的

Java锁的种类以及辨析(四):可重入锁

作者:山鸡 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及.本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑. 四.可重入锁: 本文里面讲的是广义上的可重入锁,而不是单指JAVA下的ReentrantLock. 可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响

Chipmunk僵尸物理对象的出现和解决(六)

既然出现了这个问题下面就是如何找到原因. 因为该问题不是每次都出现,偶尔反弹棒碰到五角星时才会多出一个僵尸棒,现象比较随机,较难悉知具体原因. 有时多次触碰又没有出现问题,有时短时间内每次触碰都出现问题.开始我以为是stick自身从parent删除时多次重入导致.于是希望定时将多余的stick删除掉,在GameScene中每隔5秒调用一次: -(void)clearInvalidSticks{ @synchronized(self){ NSInteger stickCount = 0; for

Java锁之可重入锁介绍_java

锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) .这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及.本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑. 四.可重入锁: 本文里面讲的是广义上的可重入锁,而不是单指JAVA下的ReentrantLock. 可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响. 在JAV