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 ...
随机推荐
- C#2.0--集合--转载车老师
集合在编程的过程中用的是非常的多,如GridViewRowCollection.ConnectionStringSettingsCollection.NameValueCollection等等.一般来 ...
- delphi中覆盖最大化消息(覆盖WM_GETMINMAXINFO消息)
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; ...
- 用lambda表达式声明委托
首先来分享一段代码: Func<int, int, int> addMethod = (int x, int y) => (x + y); 熟悉的人肯定知道这句话是什么意思,可是不熟 ...
- Maven坐标 groupId artifactId version packaging classifier name
groupId定义项目属于哪个组,这个组往往和项目所在的组织或公司存在关联.譬如在googlecode上建立一个名为myapp的项目,那么groupId就应该是com.googlecode.myapp ...
- 基于visual Studio2013解决C语言竞赛题之1066进制转化
题目 解决代码及点评 /************************************************************************/ /* ...
- [jQuery] check if an id exists - Google 网上论坛
[jQuery] check if an id exists - Google 网上论坛 From: http://docs.jquery.com/Frequently_Asked_Questions ...
- 机房收费系统总结之4——VB.NET 轻松解决判断文本框、组合框为空问题
纵观机房收费系统,判断文本框.组合框为空问题无非两种情况.第一种:判断窗体中所有文本框.组合框是否为空.第二种:判断一部分文本框.组合框是否为空.下面看看是如何实现这两种情况的. 第一种:判断窗体中所 ...
- jsoncpp 不能处理long类型数据
jsoncpp,是一个c++的解析和生成json的开源工具.假设你的c++程序须要解析或生成json,它会使这个过程变得非常easy! 可是,今天在用jsoncpp进行生成json的时候报了错误,非常 ...
- uva 11212
非原创!!! 原作者地址:http://www.hardbird.net/?p=238
- SilkTest Q&A 7
Q61.有一个用Dotnet开发的应用,有1000个为测它而录制的case,一直都运行的很正常,直到有一天… 有人改变了该应用命名空间,由于现在有一个新的window或是panel出现,所以测试脚本一 ...