在iPhone-Wax中创建NSDecimal。

我遇到了一个问题:

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

    local x=NSDecimalNumber:initWithString("2.3")

我想用以下代码行创建一个NSDecimal

   local y=x:decimalValue()

这会立即导致程序崩溃。

要创建相同的体验,您需要创建一个基本的Wax项目,并将这两行添加到AppDelegate.lua的function applicationDidFinishLaunching的最后一行。

问题:如何使其返回一个诚实的NSDecimal,以便我可以传递它?我实际上不需要看到或打印数字。


附录

  1. 尽管互联网上普遍认为NSDecimal与NSDecimalNumber非常不同。前一个是C结构体,而后一个是我的Obj-C结构体。
  2. 要使NSDecimalNumber正常工作,我需要从wax-helpers.m中注释掉第222-224行(NSNumber)和第241-246行(NSValue)。
  3. NSDecimal定义在Foundation/NSNumber.h中

运行时输出: 没什么很好的堆栈跟踪,它只是默默地死掉。在Debugger(打开断点)中,有以下(缩写)调用序列:

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

原文链接 https://stackoverflow.com/questions/6406123

点赞
stackoverflow用户813193
stackoverflow用户813193

也许你应该尝试使用 NSScanner 从字符串中创建 NSDecimal

2011-06-24 09:19:12
stackoverflow用户1200
stackoverflow用户1200

Important Edit: 好的,我很蠢(并且在简单的问题上找复杂的答案)。快速阅读 Wax 博客,我发现https://github.com/probablycorey/wax/wiki/Overview,其中提到了 toobjc 函数。因此,看起来像是...

local x = (toobjc)(NDecimalNumber:initWithString("2.3"));

将会实现你想要的效果(即防止自动 Lua 类型转换)。我可能把语法写错了,所以需要尝试一下。我保留了原始答案,以说明另一个“解决方案”。


因此,对于 Wax(我不是非常熟悉),当它将 Objective C 和 Lua 进行桥接时,它执行的一个关键操作是将它能够找到的所有 Objective C 类型转换为适当的本机 Lua 类型。其中包括 NSNumber 类型(例如 NSDecimal),它们被映射到 Lua 数字类型。

当然,您已经知道这一点,因此您对 wax-helpers.m 进行了更改。不幸的是,您所做的还不够——转换仍在发生,因此您的 NSDecimalNumber 仍然成为一个数字。根据这是否在您的 Lua 代码中使用,它似乎会导致 Lua 崩溃(尝试索引标量类型)或 Objective C 桥崩溃。我不确定为什么您只在某些情况下得到 Lua 跟踪错误(假设您的代码始终相同);这指向一些关于 Wax 内部状态的基本假设被违反的情况。

最好的解决方案是不要涉及更改 Wax。目前,即使“修复”起作用,您也完全禁用了自动强制类型转换。我认为这将破坏 Wax 的相当多的代码和习惯用法。查看 Wax,它只会执行那些子类特定 Foundation 类的对象的自动转换;任何它不知道的对象类型都将保持为对象。在这种情况下,我们陷入了 NSValueNSNumber 转换之中,所以我的第一个建议是只需在 Wax 不理解的NSDecimalNumber中包装一些类。类似于以下内容...

@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 代码的情况下添加到 Wax 中,并且使用此来携带跨桥梁的 NSDecimalValue 应该可以防止 Wax 的类型转换。当然,如果在 Lua 中使用 getDecimalValue,则结果将立即包装为 Lua number。如果您需要在 Lua 中调用底层 NSDecimalValue 的方法,请从包装定义的等效方法代理。

如果它绝对不适用于您,我可能可以找出 Wax 需要的更改。但是,维护自己的端口将非常困难,并且会破坏大量现有的 Wax 代码和示例。

顺带说一句:我不确定您在获取 Lua 中的 NSDecimal 后打算做什么。这是一个不透明的 C 结构,只能通过 Foundation 提供的 C 接口使用。

2011-06-24 19:54:38