最近新上线的一个游戏,发现线上游戏有部分功能在点击的时候出现了没有反应的情况。通过调试源码,发现是原生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. vue中如何动态的绑定图片,vue中通过data返回图片路径

    在项目中遇到需要动态的改变图片路径,图片路径并非是从后台获取过来的数据. 因此在data中必须用require加载,否则会当成字符串来处理. 效果:

  2. python用matplotlib画折线图

    折线图: import matplotlib.pyplot as plt y1=[10,13,5,40,30,60,70,12,55,25] x1=range(0,10) x2=range(0,10) ...

  3. python 获取本机的IP

    python 获取本地的IP import socket import fcntl import struct def get_ip_address(ifname): s = socket.socke ...

  4. Mysql获取最大自增ID(auto_increment)的五种方式及其特点

    在关系型数据库的表结构中,一般情况下,都会定义一个具有‘AUTO_INCREMENT’扩展属性的‘ID’字段,以确保数据表的每一条记录都有一个唯一标识. 而实际应用中,获取到最近最大的ID值是必修课之 ...

  5. 【QT】文件读写操作

    读取输出: QFile file("D:/Englishpath/QTprojects/1.dat"); if(!file.open(QIODevice::ReadOnly)) { ...

  6. Docker-集群swarm(5)

     Docker集群的概念 群集是一组运行Docker并加入集群的计算机.在此之后,您继续运行您习惯使用的Docker命令,但现在它们由群集管理器在群集上执行.群中的机器可以是物理的或虚拟的.加入群组后 ...

  7. 《Spring实战》学习笔记-第五章:构建Spring web应用

    之前一直在看<Spring实战>第三版,看到第五章时发现很多东西已经过时被废弃了,于是现在开始读<Spring实战>第四版了,章节安排与之前不同了,里面应用的应该是最新的技术. ...

  8. poj 1269

    水题.判断两条直线位置关系. 考虑平行的情况,那么 四边形的面积会相等,重合的话,四边形的面积相等且为0. 除去这两种就一定有交点. #include <cstdio> #include ...

  9. Java课程寒假之开发记账本软件(网页版)之一

    一.制定网页版记账本的基础功能 首先是下载了几个记账本APP,大致地看了一下记账本的功能:添加记录(支出,收入,自定义模板),查询流水(分类查询),账户. 二.开始做出框架 鉴于记账本有上面的功能,所 ...

  10. Mac OSX取消Apache(httpd)开机启动(转载)

    启动服务时提示Apache启动失败,80端口被占用.查看进程发现存在几个httpd. OS X自带Apache,可是默认是没有启动的.我也没有开启Web共享,怎么就开机启动了呢? 不知道是不是因为安装 ...