最近新上线的一个游戏,发现线上游戏有部分功能在点击的时候出现了没有反应的情况。通过调试源码,发现是原生OC的代码出现了崩溃,但是比较奇怪的是线上的Bugly没有任何记录,这个功能属于高频高能,而且又是非常重要的功能,所以我下定决心查个明白。后来通过查看cocos2d_lua_bindings的源码,发现是cocos2d_lua_bindings中的CCLuaObjcBridge.mm166行把这个崩溃给catch了。。所以质检部门也没发现这个错误,可能是以为游戏只是卡了下,真的是坑死人不偿命啊。

下面是CCLuaObjcBridge.mm的源码

/**
className
methodName
args
*/
int LuaObjcBridge::callObjcStaticMethod(lua_State *L)
{
if (lua_gettop(L) != || !lua_isstring(L, -) || !lua_isstring(L, -))
{
lua_pushboolean(L, );
lua_pushinteger(L, kLuaBridgeErrorInvalidParameters);
return ;
} const char *className = lua_tostring(L, -);
const char *methodName = lua_tostring(L, -);
if (!className || !methodName)
{
lua_pushboolean(L, );
lua_pushinteger(L, kLuaBridgeErrorInvalidParameters);
return ;
} Class targetClass = NSClassFromString([NSString stringWithCString:className encoding:NSUTF8StringEncoding]);
if (!targetClass)
{
lua_pushboolean(L, );
lua_pushinteger(L, kLuaBridgeErrorClassNotFound);
return ;
} SEL methodSel;
bool hasArguments = lua_istable(L, -);
if (hasArguments)
{
NSString *methodName_ = [NSString stringWithCString:methodName encoding:NSUTF8StringEncoding];
methodName_ = [NSString stringWithFormat:@"%@:", methodName_];
methodSel = NSSelectorFromString(methodName_);
}
else
{
methodSel = NSSelectorFromString([NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]);
}
if (methodSel == (SEL))
{
lua_pushboolean(L, );
lua_pushinteger(L, kLuaBridgeErrorMethodNotFound);
return ;
} NSMethodSignature *methodSig = [targetClass methodSignatureForSelector:(SEL)methodSel];
if (methodSig == nil)
{
lua_pushboolean(L, );
lua_pushinteger(L, kLuaBridgeErrorMethodSignature);
return ;
} @try {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setTarget:targetClass];
[invocation setSelector:methodSel];
NSUInteger returnLength = [methodSig methodReturnLength];
const char *returnType = [methodSig methodReturnType]; if (hasArguments)
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
lua_pushnil(L);
while (lua_next(L, -))
{
NSString *key = [NSString stringWithCString:lua_tostring(L, -) encoding:NSUTF8StringEncoding]; switch (lua_type(L, -))
{
case LUA_TNUMBER:
[dict setObject:[NSNumber numberWithFloat:lua_tonumber(L, -)] forKey:key];
break; case LUA_TBOOLEAN:
[dict setObject:[NSNumber numberWithBool:lua_toboolean(L, -)] forKey:key];
break; case LUA_TSTRING:
[dict setObject:[NSString stringWithCString:lua_tostring(L, -) encoding:NSUTF8StringEncoding]
forKey:key];
break; case LUA_TFUNCTION:
int functionId = retainLuaFunction(L, -, NULL);
[dict setObject:[NSNumber numberWithInt:functionId] forKey:key];
break;
} lua_pop(L, );
} [invocation setArgument:&dict atIndex:];
[invocation invoke];
}
else
{
[invocation invoke];
} lua_pushboolean(L, );
if (returnLength > )
{
if (strcmp(returnType, "@") == )
{
id ret;
[invocation getReturnValue:&ret];
pushValue(L, ret);
}
else if (strcmp(returnType, "c") == ) // BOOL
{
char ret;
[invocation getReturnValue:&ret];
lua_pushboolean(L, ret);
}
else if (strcmp(returnType, "i") == ) // int
{
int ret;
[invocation getReturnValue:&ret];
lua_pushinteger(L, ret);
}
else if (strcmp(returnType, "f") == ) // float
{
float ret;
[invocation getReturnValue:&ret];
lua_pushnumber(L, ret);
}
else
{
NSLog(@"not support return type = %s", returnType);
lua_pushnil(L);
}
}
else
{
lua_pushnil(L);
}
return ;
}
@catch (NSException *exception) //就是这处代码导致崩溃被catch了,正确的做法应该是测试阶段直接throw exception,上线后通过bugly手动上报这个exception对象
{ NSLog(@"EXCEPTION THROW: %@", exception); lua_pushboolean(L, ); lua_pushinteger(L, kLuaBridgeErrorExceptionOccurred); return ; } }

Cocos 2dx项目lua调用OC出现卡死但不闪退的坑的更多相关文章

  1. 苹果手机 微信调用百度地图Javascript API 频繁闪退问题

    最近在网页中调用百度地图API js大众版,但是在IOS8系统中,缩放的时候频繁闪退,安卓手机没有这个问题! 在网上查询了下,有网友回答说不要频繁的去new marker,而是初始化话一定量的mark ...

  2. Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解

    这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...

  3. Lua 与 OC 相互调用

    本文主要讲如何完成lua和object-c的相互调用.       lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,但是要接入 ...

  4. cocos2d-x Lua与OC互相调用

    1. Lua 调用OC 先看例子: hello.lua: -- 点击回调函数 local function notifymenuCallbackTest() local luaoc = require ...

  5. 在Objc项目中调用Swift

    之前的文字中记录了在Swift项目中调用OC的相关代码,比较简单直接 传送门 但是在OC中调用swift代码则不是那么的和谐,网络上很多文章业已经有点陈旧.记录步骤如下: 1.创建OC项目 (1)启动 ...

  6. Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程

    事前准备 最近给游戏添加了苹果的内购,这一块的东西也是刚刚做完,总结一下,其实这里不管是游戏还是我们普通的App添加内购这一块的东西都是差不多的,多出来的部分就是我们Lua和OC的交互的部分,以前刚开 ...

  7. Cocos2d-x下Lua调用自定义C++类和函数的最佳实践[转]

    Cocos2d-x下Lua调用C++这事之所以看起来这么复杂.网上所有的文档都没讲清楚,是因为存在5个层面的知识点: 1.在纯C环境下,把C函数注册进Lua环境,理解Lua和C之间可以互相调用的本质 ...

  8. 【转】Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

    转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...

  9. Lua调用自定义C++类

    弄了一天终于会Lua调用自定义C++类.不容易啊. 我的电脑是64位的,装了64的Python不行,装了32位的就可以了,靠!下面是报错信息 python pyyaml Cheetah全都是装32位的 ...

随机推荐

  1. Atitit 项目版本管理gitflow 与 Forking的对比与使用

    Atitit 项目版本管理gitflow 与 Forking的对比与使用 1.1. 版本管理的历史 csv>>svn >git 1 1.2. gitflow的核心是分版本管理,for ...

  2. 移动开发常用meta设置

    <!-- 视图窗口,移动端特属的标签. --> <meta name="viewport" content="width=device-width,in ...

  3. layer 关闭当前弹出层

    关闭当前框的弹出层 layer.close(layer.index); 刷新父层 parent.location.reload(); // 父页面刷新 关闭iframe 弹出的全屏层 var inde ...

  4. C语言 · 积分之迷

    标题:积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C. 为了促销,每件商品都会返固定的积分. 小明开业第一天收到了三笔订单: 第一笔:3个A + 7个B + 1个C,共返积分:315 ...

  5. Java开发面试题汇总整理

    又是金三银四的时候,我希望这份面试题能够祝你一臂之力! 自我和项目相关 1.自我介绍 2.你觉得自己的优点是?你觉得自己有啥缺点? 3.你有哪些 offer? 4.你为什么要离开上家公司?你上家公司在 ...

  6. ABBYY PDF Transformer+ 给你好看

    ABBYY PDF Transformer+是一个新的.全面的巧妙解决PDF文档的工具,它将泰比的光学字符识别(OCR)技术和Adobe®PDF技术完美结合,以确保实现便捷地处理任何类型的PDF文件, ...

  7. [hive] hive 内部表和外部表

    1.内部表 hive (test1)> create table com_inner_person(id int,name string,age int,ctime timestamp) row ...

  8. Nginx 反向代理获取设备真实的IP地址

    package com.das.common.util; import org.apache.commons.lang3.StringUtils; import org.springframework ...

  9. gcc编译c语言程序

    编译:当前源代码编译成二进制目标文件(.obj文件) 链接(link):将生成的.obj文件与库文件.lib等文件链接,生成可执行文件(.exe文件).   一个现代编译器的主要工作流程如下: 源程序 ...

  10. shell模板-跨目录执行,彩色输出,临时文件,行遍历文件

    参数检查 #!/bin/bash set -e if [ ! -n "$1" ];then echo "Usage: #cmd <> []" exi ...