试图在iPhone-Wax中创建NSDecimal

时间:2011-06-20 01:26:02

标签: objective-c cocoa-touch lua iphone-wax

这是我面临的一个问题:

我使用行

在Wax中创建一个NSDecimalNumber
    local x=NSDecimalNumber:initWithString("2.3") 

出于这个原因,我想用以下内容创建一个NSDecimal 行

   local y=x:decimalValue() 

这会立即导致程序崩溃。

要创建相同的体验,您需要创建一个基本的蜡项目,并在AppDelegate.lua中添加两行作为 function applicationDidFinishLaunching 的lat行。

问题:我怎样才能让它返回一个诚实的NSDecimal,我可以 传递?我实际上并不需要自己查看或打印这个号码。


附录

  1. 尽管人们普遍相信互联网,但NSDecimal却非常不同 来自NSDecimalNumber。第一个是C结构,第二个是 一个Obj-C结构,我很好地工作。
  2. 要让NSDecimalNumber起作用,我需要注释掉第222-224行 来自蜡助手的(NSNumber)和241-246(NSValue)。
  3. NSDecimal在Foundation / NSNumber.h
  4. 中定义

    运行时的输出: 没有太多的堆栈跟踪,它只是默默地死亡。在调试器中(打开断点),有以下(缩写)调用序列:

    #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正在尝试为数值调用方法。

2 个答案:

答案 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类的子类;任何它不知道的对象类型仍然是一个对象。在这种情况下,我们遇到了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所需的更改。但它成为一个维护自己的端口并破坏大量现有Wax代码和示例的伤害世界。

切向:一旦你在Lua中获得了NSDecimal,我不确定你打算做什么。它是一个不透明的C结构,只能通过Foundation提供的C接口使用。

答案 1 :(得分:0)

也许您应该尝试NSScanner从字符串创建NSDecimal