• do{}while(0)与CC_BREAK_IF的绝妙搭配


    从一開始认为没有必要,到认为很好用。我经历了大概两个月的时间,以下来总结一下什么情况下使用这样的结构吧。

    第一种情况:当载入文件的时候,假设载入文件失败,须要报错的时候。

    当前,能够用try{}catch(){}finally{}这样的结构。可是这样做会极大的添加编译后文件的大小。使用do{}while(0)加上CC_BREAK_IF就能实现一样的效果,并且不添加文件的大小。

    以下是一个样例:

    bool GameScene::setScene()
    {
    	do{
    		auto node = SceneReader::getInstance()->createNodeWithSceneFile("publish/GameScene.csb");  
    		CC_BREAK_IF(!node);
    		m_UI_Background->addChild(node);
    
    		auto Checkerboard = (ComRender*)(node->getChildByTag(10009)->getComponent("GUIComponent"));
    		CheckerboardUI = Checkerboard->getNode();
    		//设置button
    		m_btn_Setting = dynamic_cast<Button*>(CheckerboardUI->getChildByName("Button_Setting"));
    		CC_BREAK_IF(!m_btn_Setting);
    		//音乐button
    		m_btn_Music = dynamic_cast<Button*>(CheckerboardUI->getChildByName("Button_Music"));
    		CC_BREAK_IF(!m_btn_Music);
    		//棋盘锁
    		m_btn_Lock = dynamic_cast<Button*>(CheckerboardUI->getChildByName("Button_Lock"));
    		CC_BREAK_IF(!m_btn_Lock);
    		//棋盘图片
    		m_Image_Checkerboard = dynamic_cast<ImageView*>(CheckerboardUI->getChildByName("Image_Checkerboard"));
    		CC_BREAK_IF(!m_Image_Checkerboard);
    		m_Checkerboard = Checkerboard::create(m_Image_Checkerboard);
    		auto SelectPeople = (ComRender*)(node->getChildByTag(10031)->getComponent("GUIComponent"));
    		SelectPeopleUI = SelectPeople->getNode();
    		this->setCampBtn();
    
    		return true;
    	}while(0);
    	CCLOG("ERROR:Load Resources Fail in GameScene::setScene");
    	return false;
    }

    假设在中途出现不论什么一个变量运行后还是nullptr。那么就CC_BREAK_IF,然后显示错误日志。最后返回false给上层函数进行处理。这种处理方式是不是既优雅又方便高速,又避免了可能错误使用空指针。


    另外一种情况:当不管怎样都须要在函数最后进行清理操作的时候。

    以下举一个比較典型的样例,就是在函数开头声明了一个new的指针(非智能指针),依照正常的流程,须要delete。可是我们无法保证程序会不会在中途就return了,由于兴许的维护者并不知道还有这个清除操作须要运行。以下是一个对照样例:

    //error
    void test()
    {
    	GameScene* gamescene = new GameScene;
    	// doSomething...
    	if(gamescene->getChildByTag(111) == nullptr)
    	{
    		return;
    	}
    	// doSomething...
    	delete gamescene;
    	gamescene = nullptr;
    }
    
    //right
    void test1()
    {
    	GameScene* gamescene = new GameScene;
    	do{
    		// doSomething...
    		CC_BREAK_IF(gamescene->getChildByTag(111) == nullptr);
    		// doSomething...
    	}while(0);
    	delete gamescene;
    	gamescene = nullptr;
    }

    使用CC_BREAK_IF能够保证永远都会运行到最后两行,也就不会出现内存泄露。


    可是这个组合也不是万能的,以下就说一个不适合这样的结构的情况吧。

    当do{}while(0)的括号里存在循环的时候,就不适用这个组合了。由于break毕竟仅仅能跳出一层循环,以下是一个样例:

    void test2()
    {
    	do{
    		for(int i = 0;i <5;++i)
    		{
    			// doSomething...
    			CC_BREAK_IF(i>4); 
    			// doSomething...
    		}
    		CCLOG("永远显示这一行日志");
    	}while(0);
    }

    我们希望的是,CC_BREAK_IF能跳出do{}while(0)循环。可是实际上。仅仅跳出了for循环,所以使用do{}while(0)和CC_BREAK_IF的时候,须要确保其内部不能存在其它循环,假设存在循环,还是建议使用try{}catch(){}

  • 相关阅读:
    websocket1
    webpack 入门三
    weboack 入门二
    webpack 入门一
    输入一个url发生了什么
    http详解
    JavaScript对象详解
    javaScript垃圾回收机制
    js数据类型与隐式类型转换
    iOS证书申请、AppStore上架流程
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6767916.html
Copyright © 2020-2023  润新知