• 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
    ",
                  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})

  • 相关阅读:
    shell 表达式
    manjaro 换源到中国并按照速度排序
    ORA-01950:对表空间 'USERS' 无权限
    normal 普通身份 sysdba 系统管理员身份 sysoper 系统操作员身份 dba和sysdba
    学生选课数据库SQL语句练习题
    多线程编程
    补充知识点
    输入输出
    集合作业
    银行(1)0925
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3938099.html
Copyright © 2020-2023  润新知