標籤: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 'next'錯調試