这是我面临的一个问题:
我使用行
在Wax中创建一个NSDecimalNumber local x=NSDecimalNumber:initWithString("2.3")
出于这个原因,我想用以下内容创建一个NSDecimal 行
local y=x:decimalValue()
这会立即导致程序崩溃。
要创建相同的体验,您需要创建一个基本的蜡项目,并在AppDelegate.lua中添加两行作为 function applicationDidFinishLaunching 的lat行。
问题:我怎样才能让它返回一个诚实的NSDecimal,我可以 传递?我实际上并不需要自己查看或打印这个号码。
附录
运行时的输出: 没有太多的堆栈跟踪,它只是默默地死亡。在调试器中(打开断点),有以下(缩写)调用序列:
#0 0x027553f4 in objc_exception_throw
#1 0x0256e8d6 in __NSGetSizeAndAlignment
#2 0x0256ebd9 in __NSGetSizeAndAlignment
#3 0x025747b8 in __NSMS1
#4 0x02573f9c in +[NSMethodSignature signatureWithObjCTypes:]
#5 0x000342d0 in wax_selectorForInstance at wax_helpers.m:557
#6 0x00035bc2 in __index at wax_instance.m:303
#7 0x000181b9 in luaD_precall at ldo.c:319
#8 0x00018405 in luaD_call at ldo.c:376
#9 0x0002c488 in callTMres at lvm.c:88
#10 0x0002c74a in luaV_gettable at lvm.c:125
#11 0x0002dd26 in luaV_execute at lvm.c:467
#12 0x0001841c in luaD_call at ldo.c:377
#13 0x0000ddc8 in f_call at lapi.c:800
#14 0x0001758a in luaD_rawrunprotected at ldo.c:116
#15 0x0001879a in luaD_pcall at ldo.c:463
#16 0x0000de65 in lua_pcall at lapi.c:821
#17 0x00034e60 in wax_pcall at wax_helpers.m:826
#18 0x00036be4 in pcallUserdata at wax_instance.m:580
#19 0x00036edc in wax_id_call at wax_instance.m:627
有时会出现以下微小的堆栈跟踪:
wTest[36403:207] PANIC:
Error
-----
Error calling 'applicationDidFinishLaunching:' on lua object '<AppDelegate: 0x6300e50>'
data/scripts/AppDelegate.lua:39: attempt to index local 'x' (a number value)
stack traceback:
[C]: ?
data/scripts/AppDelegate.lua:39: in function <data/scripts/AppDelegate.lua:19>
这与调试器提供的内容相符:Wax正在尝试为数值调用方法。
答案 0 :(得分:2)
重要编辑:好的,我很愚蠢(寻找简单问题的复杂答案)。快速阅读Wax博客,我找到了https://github.com/probablycorey/wax/wiki/Overview,其中提到了toobjc
函数。因此,它看起来像...... ...
local x = (toobjc)(NDecimalNumber:initWithString("2.3"));
将执行您想要的操作(即阻止自动Lua类型转换)。我的语法可能略有错误,所以试验一下。我在下面留下原来的答案来说明另一个“解决方案”。
因此,查看Wax(我并不熟悉),在桥接Objective C和Lua时执行的一个关键操作是将所有Objective C类型转换为合适的本机Lua类型。这包括映射到Lua数字类型的NSNumber
类型(例如NSDecimal
)。
当然,您已经知道这一点,因此您对wax-helpers.m
进行了更改。唉,你所做的还不够 - 转换仍然在进行,因此你的NSDecimalNumber
仍然是一个数字。看来,根据你的Lua代码是否使用它,Lua会爆炸(尝试索引标量类型),或者Objective C桥爆炸。我不知道你为什么只得到Lua跟踪错误有时(假设你的代码总是相同的);它指出了一些关于内部蜡状态被违反的基本假设。
最佳解决方案是不涉及更改Wax的解决方案。目前,即使“修复”确实有效,您也完全禁用了类型之间的自动强制。我认为,这将打破相当多的Wax代码和习语。查看Wax,它只会对类型进行自动转换,这些类型是它特定理解的某些Foundation类的子类;任何它不知道的对象类型仍然是一个对象。在这种情况下,我们遇到了NSValue
和NSNumber
转换,因此我的第一个建议是简单地将NSDecimalNumber
包装在Wax不理解的某个类中。有点像...
@interface MyDecimalWrapper : NSObject
{
NSDecimalValue *myDecimal;
}
- (NSDecimalValue*)getDecimalValue;
- (NSDecimal*)getDecimal;
@end
@implementation MyDecimalWrapper
- (NSDecimalValue*)getDecimalValue { return [[myDecimal retain] autorelease] }
- (NSDecimal*)getDecimal { return [myDecimal decimalValue]; }
@end
这可以添加到Wax而不会显着改变它的代码,并且使用它在桥上传送NSDecimalValue
应该可以防止Wax的类型转换。当然,如果你在Lua中使用getDecimalValue
,结果将立即被包装到Lua number
中。如果你需要在Lua中的基础NSDecimalValue
上调用方法,只需从包装器上定义的等效方法代理它们。
如果这绝对不适合您,我可能会解决Wax所需的更改。但它将成为一个维护自己的端口并破坏大量现有Wax代码和示例的伤害世界。
切向:一旦你在Lua中获得了NSDecimal
,我不确定你打算做什么。它是一个不透明的C结构,只能通过Foundation提供的C接口使用。
答案 1 :(得分:0)
也许您应该尝试NSScanner
从字符串创建NSDecimal
。