这是我面临的一个问题:
我用以下代码在Wax中创建一个NSDecimalNumber
local x=NSDecimalNumber:initWithString("2.3")
为此,我想创建一个NSDecimal与以下内容
线
local y=x:decimalValue()
这会立即使程序崩溃。
要创建相同的体验,您需要创建一个基本的蜡项目,并将这两行添加为AppDelegate.lua中函数applicationDidFinishLaunching 的latt行。
问题:如何获取此返回的诚实NSDecimal,我可以
过去吗?我实际上不需要自己查看或打印该号码。
附录
来自NSDecimalNumber。第一个是C结构,第二个是
我很好用的Obj-C结构。
(NSNumber)和241-246(NSValue),来自wax-helpers.m。
运行时输出:
没有太多的堆栈跟踪,只是默默地消失了。在调试器(打开断点)中,有以下(缩写)调用序列:
#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尝试为数字值调用方法。
最佳答案
重要提示编辑:好的,我很愚蠢(正在寻找简单问题的复杂答案)。快速阅读Wax博客后,我发现https://github.com/probablycorey/wax/wiki/Overview,其中提到了toobjc
函数。就这样,看起来像...
local x = (toobjc)(NDecimalNumber:initWithString("2.3"));
将执行您想要的操作(即阻止自动Lua类型转换)。我的语法可能有些错误,因此请尝试一下。我在下面留下了原始答案,以说明另一个“解决方案”。
因此,看一下Wax(我并不十分熟悉),在将Objective C和Lua桥接时,它执行的一个关键 Action 是将它可以转换的所有Objective C类型转换为合适的 native Lua类型。这包括映射到Lua数字类型的
NSNumber
类型(例如NSDecimal
)。当然,您已经知道这一点,因此您对
wax-helpers.m
进行了更改。 las,您所做的还不够-转换仍在进行,因此NSDecimalNumber
仍然是数字。看来,取决于是否在您的Lua代码中使用了它,Lua会崩溃(尝试对标量类型建立索引),还是Objective C桥会崩溃。我不确定为什么有时只收到Lua跟踪错误(假设您的代码始终相同);它指出了有关内部蜡状态被违反的一些基本假设。最好的解决方案是不涉及更换蜡的解决方案。此刻,即使“修复”成功了,您也完全禁用了类型之间的自动强制。我认为,这将破坏很多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代码和示例。
切线:我不确定在Lua中使用
NSDecimal
后打算做什么。这是一个不透明的C结构,只能通过Foundation提供的C接口(interface)使用。