CCLuaObjcBridge调Objective-C方法传索引数组报invalid key to 'next'错调试
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 'next'错调试的更多相关文章
- 关于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 ...
- wcf上传字节数组报错问题
为了实现上传大文件所以我们要如下设置最大值,其中security是设置访问服务的认证,此处是把它设置成为不认证,transferMode就是设置运用流的模式 <webHttpBinding> ...
- LeetCode竞赛题:K 次取反后最大化的数组和(给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。)
给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修改数组后 ...
- js原生方法传参的细节(面试必问)
废话不说,直接上题. slice(),接收两个参数,第一个为开始index(从0开始),第二个为结束的index(也是从0开始,但是不包括index本身,只到index-1).返回值是截取的数组,原数 ...
- java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列
1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...
- JS 索引数组、关联数组和静态数组、动态数组
JS 索引数组.关联数组和静态数组.动态数组 数组分类: 1.从数组的下标分为索引数组.关联数组 var ary1 = [1,3,5,8]; //按索引去取数组元素,从0开始(当然某些语言实现从1开始 ...
- mongodb-$type、limit、skip、sort方法、索引、聚合
一.$type操作符 $type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果. MongoDB 中可以使用的类型如下表所示: 类型 数字 备注 Double 1 String 2 ...
- C#高级功能(四)扩展方法和索引
扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.扩展方法被定义为静态方法,但 ...
- wrong number of arguments,java方法反射时数组参数的坑
java方法中只有一个参数是数组,反射的时候我们不能想当然的传歌数组进去,传数组进去的时候表示多个参数. 两个数组不是一个意思啊. 我们应该把数组转为objet,这样才表示一个参数. import j ...
随机推荐
- xcode6 中增加SDWebImage/SDWebImageDownloaderOperation.m报错解决方法
报错报错:Use of undeclared identifier '_executing' / '_finished': 解决方法例如以下:
- Python中字符串的方法及注释
先整理到这里:用的时候便于查询.相当于自己的资料库吧. capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) ...
- 使用BigDecimal来进行精确计算
在一些以金融等行业中的计算是需要十分精确的,即使我们使用像double这样的类型,由于浮点数的原因,会使得数据计算变得不精确,例如下面的例子: double a = 0.1; double b = 0 ...
- 如何在一个jpg图片上面叠加文字
1.将jpg转为bmp格式 2.在bmp文件上写上所需文字 3.将写入文字的bmp文件重新转为jpg格式 http://dev.csdn.net/develop/article/22/22948.sh ...
- Oracle表连接总结
1 简述 1) 两个表的连接,是通过将一个表中的一列或者多列同另一个表中的列链接而建立起来的.用来连接两张表的表达式组成了连接条件.当连接成功后,第二张表中的数据就同第一张表连接起来了,并形成了复合结 ...
- ViEmu For VS2010 3.0 解除30天限制的方法
一.概述 首先,ViEmu试用版在安装时会记录安装的时间,用于判断是否已经过了限制的时间,这个时间记录在注册表中 以本人的机器(WIN7X64)为例,它记录在 HKEY_CLASSES_ROOT\Wo ...
- ZigBee研究之旅(一)
*********************************************************************** 以下有引用webee公司的文档的内容,版权属于webee ...
- Prime Path (poj 3126 bfs)
Language: Default Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11703 Ac ...
- Processing_百度百科
Processing_百度百科 Processing
- 对数的操作 开始我的JAVA历程
package Text; public class Sumn { public static void main (String args[]){ System.out.println(" ...