CCLuaObjcBridge是cocos2d-x系列引擎与Objective-C进行交互的“桥梁”,老廖的quick-cocos2d-x在其framework进行了简单了封装,封装到了luaoc类中,大体能够看成:

luaoc.callStaticMethod = CCLuaObjcBridge.callStaticMethod

函数原型例如以下:

--[[
调用Objective-C中的静态方法
@param string className 类名
@param string methodName 方法名
@param table args 參数
]]
function luaoc.callStaticMethod(className, methodName, args)
end

假定有下面Objective-C静态方法:

#import <Foundation/Foundation.h>

@interface SdkApi : NSObject

+ (void)init:(NSDictionary*)dict;

@end

当尝试用下面參数调用时,会报“invalid key to 'next'“错:

luaoc.callStaticMethod("SdkApi", "init", {"platform", true})

非常奇怪的错误,一步一步调试,进到CCLuaObjcBridge.mm,定位到lua_next行代码:

        if (hasArguments)
{
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
lua_pushnil(L);
while (lua_next(L, -2))
{
NSString *key = [NSString stringWithCString:lua_tostring(L, -2) encoding:NSUTF8StringEncoding]; switch (lua_type(L, -1))
{
case LUA_TNUMBER:
[dict setObject:[NSNumber numberWithFloat:lua_tonumber(L, -1)] forKey:key];
break; case LUA_TBOOLEAN:
[dict setObject:[NSNumber numberWithBool:lua_toboolean(L, -1)] forKey:key];
break; case LUA_TSTRING:
[dict setObject:[NSString stringWithCString:lua_tostring(L, -1) encoding:NSUTF8StringEncoding]
forKey:key];
break; case LUA_TFUNCTION:
int functionId = retainLuaFunction(L, -1, NULL);
[dict setObject:[NSNumber numberWithInt:functionId] forKey:key];
break;
} lua_pop(L, 1);
} [invocation setArgument:&dict atIndex:2];
[invocation invoke];
}
else
{
[invocation invoke];
}

粗略阅读了一下代码,没有发现什么异常,于是去查官方文档,最终有了发现:

int lua_next (lua_State *L, int index);

Pops a key from the stack, and pushes a key–value pair from the table at the given index (the "next" pair after the given key). If there are no more elements in the table, then lua_next returns 0 (and pushes nothing).

A typical traversal looks like this:

     /* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
} While traversing a table, do not call lua_tolstring directly on a key, unless you know that the key is actually a string. Recall that lua_tolstring may change the value at the given index; this confuses the next call to lua_next. See function next for the caveats of modifying the table during its traversal.

大体意思是说在遍历table时,除非你知道key是string类型,否则不要直接对key进行lua_tolstring操作,这是由于lua_tolstring操作可能改动指定index处的值,从而使下一次调用lua_next混淆。

简言之就是:lua_tolstring可能会破坏table的原有结构,所以不要在遍历的时候对key进行lua_tolstring操作。

而lua_tostring终于调用的也是lua_tolstring,所以问题便出在这了。

要避免此错误,不传索引数组便可解决,如:

luaoc.callStaticMethod("SdkApi", "init", {platform = "platform", debug = true})

CCLuaObjcBridge调Objective-C方法传索引数组报invalid key to &#39;next&#39;错调试的更多相关文章

  1. 关于PHP索引数组unset某key后json_encode相关问题踩坑记录

    <?php $a = [1,2,3]; var_dump(json_encode($a)); #string(7) "[1,2,3]" unset($a[0]); var_d ...

  2. wcf上传字节数组报错问题

    为了实现上传大文件所以我们要如下设置最大值,其中security是设置访问服务的认证,此处是把它设置成为不认证,transferMode就是设置运用流的模式 <webHttpBinding> ...

  3. LeetCode竞赛题:K 次取反后最大化的数组和(给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。)

    给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修改数组后 ...

  4. js原生方法传参的细节(面试必问)

    废话不说,直接上题. slice(),接收两个参数,第一个为开始index(从0开始),第二个为结束的index(也是从0开始,但是不包括index本身,只到index-1).返回值是截取的数组,原数 ...

  5. java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列

    1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...

  6. JS 索引数组、关联数组和静态数组、动态数组

    JS 索引数组.关联数组和静态数组.动态数组 数组分类: 1.从数组的下标分为索引数组.关联数组 var ary1 = [1,3,5,8]; //按索引去取数组元素,从0开始(当然某些语言实现从1开始 ...

  7. mongodb-$type、limit、skip、sort方法、索引、聚合

    一.$type操作符 $type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果. MongoDB 中可以使用的类型如下表所示: 类型 数字 备注 Double 1   String 2 ...

  8. C#高级功能(四)扩展方法和索引

    扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.扩展方法被定义为静态方法,但 ...

  9. wrong number of arguments,java方法反射时数组参数的坑

    java方法中只有一个参数是数组,反射的时候我们不能想当然的传歌数组进去,传数组进去的时候表示多个参数. 两个数组不是一个意思啊. 我们应该把数组转为objet,这样才表示一个参数. import j ...

随机推荐

  1. 博弈问题之SG函数博弈小结

    SG函数: 给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移 动者判负.事实上,这个游戏可以认为是所有Impartial Combinatorial Ga ...

  2. Poj 3771 hdu 3405

    poj 3771 http://poj.org/problem?id=3771 wiki Prim http://zh.wikipedia.org/wiki/%E6%99%AE%E6%9E%97%E5 ...

  3. PHP移动互联网开发笔记(5)——文件的上传下载

    原文地址:http://www.php100.com/html/php/rumen/2014/0326/6706.html 一.文件的上传 1.client设置: (1).在 标签中将enctype和 ...

  4. 在Java中使用MD5和BASE64

    MD5: 在上一篇<Servlet的学习之Session(5)>中,为了能使获取的所有随机数都能有相同的位数,我们采用MD5获取随机数的消息摘要(或称数据指纹.数据摘要等等). MD5可以 ...

  5. QNX---- interrupts 例程

    #include <sys/neutrino.h> int interruptID; const struct sigevent * intHandler (void *arg, int ...

  6. Http请求工具实例编写(超长,比较清楚)

    HTTP协议工作方式首先客户端发送一个请求(request)给服务器,服务器在接收到这个请求后将生成一个响应(response)返回给客户端.在这个通信的过程中HTTP协议在以下4个方面做了规定:1. ...

  7. 【ASP.NET Web API教程】2.3.7 创建首页

    原文:[ASP.NET Web API教程]2.3.7 创建首页 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. Part 7: Crea ...

  8. CSipSimple最新版本号

    要使用CSipSimple有两种方法:第一种是不编译jni,另外一种是编译jni. 这里介绍的是第一种:不编译jni. 首先,用SVNclient检出CSipSimple源代码:svn checkou ...

  9. cocos2d-x lua 内存回收

    使用cocos2d-x lua架构,游戏中存在两种内存回收方式. 1.cocos2d-x 本身内存回收 PS:假设在lua在创建一个类,继承cocos2d-x的一个类A,则该A也遵循cocos2d-x ...

  10. MongoDB学习笔记(二) 通过samus驱动实现基本数据操作

    传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成,MongoDB是由(database).集合(collection).文档对象(documen ...