Cocos 2dx项目lua调用OC出现卡死但不闪退的坑
最近新上线的一个游戏,发现线上游戏有部分功能在点击的时候出现了没有反应的情况。通过调试源码,发现是原生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出现卡死但不闪退的坑的更多相关文章
- 苹果手机 微信调用百度地图Javascript API 频繁闪退问题
最近在网页中调用百度地图API js大众版,但是在IOS8系统中,缩放的时候频繁闪退,安卓手机没有这个问题! 在网上查询了下,有网友回答说不要频繁的去new marker,而是初始化话一定量的mark ...
- Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解
这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...
- Lua 与 OC 相互调用
本文主要讲如何完成lua和object-c的相互调用. lua是一种脚本语言,可以方便的移植到各种宿主语言中,并且可以支持热更新,在游戏开发中也能当做主要的语言来编写游戏的逻辑,但是要接入 ...
- cocos2d-x Lua与OC互相调用
1. Lua 调用OC 先看例子: hello.lua: -- 点击回调函数 local function notifymenuCallbackTest() local luaoc = require ...
- 在Objc项目中调用Swift
之前的文字中记录了在Swift项目中调用OC的相关代码,比较简单直接 传送门 但是在OC中调用swift代码则不是那么的和谐,网络上很多文章业已经有点陈旧.记录步骤如下: 1.创建OC项目 (1)启动 ...
- Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程
事前准备 最近给游戏添加了苹果的内购,这一块的东西也是刚刚做完,总结一下,其实这里不管是游戏还是我们普通的App添加内购这一块的东西都是差不多的,多出来的部分就是我们Lua和OC的交互的部分,以前刚开 ...
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践[转]
Cocos2d-x下Lua调用C++这事之所以看起来这么复杂.网上所有的文档都没讲清楚,是因为存在5个层面的知识点: 1.在纯C环境下,把C函数注册进Lua环境,理解Lua和C之间可以互相调用的本质 ...
- 【转】Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...
- Lua调用自定义C++类
弄了一天终于会Lua调用自定义C++类.不容易啊. 我的电脑是64位的,装了64的Python不行,装了32位的就可以了,靠!下面是报错信息 python pyyaml Cheetah全都是装32位的 ...
随机推荐
- Delphi Format 格式化数字
Format('x=%d', [12]); //'x=12' //最普通Format('x=%3d', [12]); //'x= 12' //指定宽度Format('x=%f', [12.0]); / ...
- 基于Kafka的生产者消费者消息处理本地调试
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/68174111冷血之心的博客) Kafka下载地址:http://d ...
- 谈一谈iOS事件的产生和传递
谈一谈iOS事件的产生和传递 1.事件的产生 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中. UIApplication会从事件队列中取出最前面的事件,并将事件 ...
- (8) MySQL主从复制架构使用方法
一. 单个数据库服务器的缺点 数据库服务器存在单点问题 数据库服务器资源无法满足增长的读写请求 高峰时数据库连接数经常超过上限 二. 如何解决单点问题 增加额外的数据库服务器,组建数据库集群 同一集群 ...
- 理解REST和RPC
REST 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 网站开发,完全可以采用软件开发的模式.但是传统上,软件和网络是两个不同的领域,很少有交集:软件开发主要针对单机环境,网络则主要研究 ...
- 当 return 遇到 try
. . . . . 今天有同事和我探讨在群里看到的一道有趣的题目,在探讨的过程中让我搞清楚了一些曾经模糊的概念,特此记录下来. 题目给出如下代码,问运行后打印的结果是什么. public static ...
- flume学习笔记——安装和使用
Flume是一个分布式.可靠.和高可用的海量日志聚合的系统,支持在系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力. Flume是一 ...
- 【转】Linux netstat命令详解,高级面试必备
简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Member ...
- Spring 注入枚举数组
在spring的配置文件xml中 示例: <!--注入枚举数組--> <bean id="writeMapNullValue" class="org.s ...
- osg shader 相机观察矩阵逆矩阵 求顶点世界坐标
uniform mat4 osg_ViewMatrixInverse;//osg内置uniform void main() { vec4 posWorld = osg_ViewMatrixInvers ...