Trying to create NSDecimal in iPhone-Wax

Here is the problem I am facing:

I create an NSDecimalNumber in Wax with a line

local x=NSDecimalNumber:initWithString("2.3") 

From this, I would like to create an NSDecimal with the following line

  local y=x:decimalValue() 

This will cause the program to crash.

To create the same experience, you need to create a basic wax project and add two lines in the form of Latin function applicationDidFinishLaunching lines in AppDelegate.lua.

Question: How can I get this to return an honest NSDecimal that I can pass on? I really don't need to see or print the number myself.


Applications

  • Despite the widespread opinion on the Internet, NSDecimal is very different from NSDecimalNumber. The first is the C structure, the second is the Obj-C structure, which I work very well with.
  • To get NSDecimalNumber to work, I need to comment on lines 222-224 (NSNumber) and 241-246 (NSValue) from wax helpers.
  • NSDecimal is defined in Foundation / NSNumber.h

Startup Conclusion: There is not much stack trace, it just dies quietly. In Debugger (with checkpoints enabled), the following (shortened) call sequence exists:

 #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 

Sometimes the following tiny stack trace exists:

 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> 

This corresponds to what the debugger gives: Wax tries to call the method for the value of the number.

+6
source share
2 answers

Important change : Well, I'm stupid (and looking for complex answers to simple questions). A quick read of the Wax blog and I find https://github.com/probablycorey/wax/wiki/Overview which mentions the toobjc function. So it looks like ...

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

will do what you want (i.e. prevent automatic conversion of type Lua). Maybe my syntax is a little wrong, so experiment. I lost my original answer below to illustrate another β€œsolution”.


So, looking at the wax (which I don't know very well), one key act that it performs when binding Objective-C and Lua is to convert all Objective-C types to their corresponding native Lua types. This includes NSNumber types (such as NSDecimal ) that map to Lua number types.

Of course, you already know this, therefore, your changes to wax-helpers.m . Alas, what you have done is not enough. Conversions still occur, and therefore, your NSDecimalNumber is still becoming a number. It looks like depending on whether it is used in your Lua code, Lua explodes (trying to index the scalar type), or the Objective-C bridge explodes. I'm not sure why you sometimes get a Lua trace error (if your code is always identical); this indicates some basic assumptions about the violation of the internal state of the wax.

A better solution would be one that does not require a wax change. At this point, even if the β€œfix” does work, you have completely disabled automatic coercion between types. This, I think, will break a lot of wax codes and idioms. Looking at Wax, it will only perform automatic conversions for types that are subclasses of some Foundation classes that it specifically understands; any type of object that he does not know about remains an object. In this case, we got into the conversion of NSValue and NSNumber , so my first suggestion is to simply wrap NSDecimalNumber in some class that Wax does not understand. Sort of...

 @interface MyDecimalWrapper : NSObject { NSDecimalValue *myDecimal; } - (NSDecimalValue*)getDecimalValue; - (NSDecimal*)getDecimal; @end @implementation MyDecimalWrapper - (NSDecimalValue*)getDecimalValue { return [[myDecimal retain] autorelease] } - (NSDecimal*)getDecimal { return [myDecimal decimalValue]; } @end 

This can be added to Wax without significant code changes, and using it to port NSDecimalValue across the bridge should prevent Wax type conversion. Of course, if you use getDecimalValue inside Lua, the result will be quickly wrapped in a Lua number . If you need to call methods in the base NSDecimalValue in Lua, simply proxy them from the equivalent methods defined on the wrapper.

If this doesn't work for you at all, I can probably change the changes necessary for Wax. But it will be a world of pain supporting your own port, and a breakdown of many existing wax codes and examples.

Tangentially: I'm not sure what you intend to do with NSDecimal when you have one in Lua. This is an opaque C structure that can only be used through the C interface provided by Foundation.

+2
source

Maybe you should try NSScanner to create an NSDecimal from a string.

0
source

Source: https://habr.com/ru/post/890886/


All Articles