这是我面临的一个问题:

我用以下代码在Wax中创建一个NSDecimalNumber

    local x=NSDecimalNumber:initWithString("2.3")

为此,我想创建一个NSDecimal与以下内容
线
   local y=x:decimalValue()

这会立即使程序崩溃。

要创建相同的体验,您需要创建一个基本的蜡项目,并将这两行添加为AppDelegate.lua中函数applicationDidFinishLaunching 的latt行。

问题:如何获取此返回的诚实NSDecimal,我可以
过去吗?我实际上不需要自己查看或打印该号码。

附录
  • 尽管互联网上普遍认为,NSDecimal还是有很大不同
    来自NSDecimalNumber。第一个是C结构,第二个是
    我很好用的Obj-C结构。
  • 要使NSDecimalNumber工作,我需要注释掉222-224行
    (NSNumber)和241-246(NSValue),来自wax-helpers.m。
  • NSDecimal在Foundation/NSNumber.h中定义


  • 运行时输出:
    没有太多的堆栈跟踪,只是默默地消失了。在调试器(打开断点)中,有以下(缩写)调用序列:
    #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类的子类进行自动转换。它不知道的任何对象类型仍然是一个对象。在这种情况下,我们陷入了NSValueNSNumber转换中,因此我的第一个建议是将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)使用。

    09-27 03:27