CCLuaObjcBridge調Objective-C方法傳索引數組報invalid key to 'next'錯調試

來源:互聯網
上載者:User

標籤:blog   os   io   for   ar   2014   art   問題   div   

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;錯調試

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.