On 22 Feb 2014, at 08:32, Ken Thomases <k...@codeweavers.com> wrote:

> There's no one representation of an NSNumber's content.
I think that this is the foundation of things.

What there is is a reported representation as given by -objCType.

The docs say, as I am sure you know:

“
NSNumber

objCType
Returns a C string containing the Objective-C type of the data contained in the 
receiver.

- (const char *)objCType
Return Value
A C string containing the Objective-C type of the data contained in the 
receiver, as encoded by the @encode() compiler directive.
“

Now I don’t care know how NSNumber persists its value nor with what type it was 
initialised. What I do care about in this case is what -objCType returns.
If I create a NSNumber like so:

NSNumber *n = @((int)5);

Then [n objCType] returns “i”.
From this I conclude that the canonical/reported representation is an int and I 
proceed accordingly.
And that’s all that I require.

The Mono method declares I need a pointer to an int.
If my Obj-C argument id object says, yes, I have a canonical/reported int and 
provide a pointer to such, then we are good to go.

I can define a complex number class.
MYComplexNumber * cn = [MYComplexNumber complexNumberWithString:@“5,2"];
This can return “i” for -objCType and that’s okay.
Now if I initialise it with @“5.5,2” -objCType may respond with “f”.
Now that is not okay. I have a unexpected type but this is something that I can 
detect and handle, likely by raising an exception.

> Keep in mind that NSDecimalNumber is-a NSNumber

Your point about NSNumber subclasses such as NSDecimaNumber is well made and a 
case in point.
It turns out that NSDecimaNumber returns “d” for double.
My category will produce a pointer to a double representation of the 
NSDecimaNumber.
And that’s okay.
NSDecimaNumber instances can safely(!!) be used as arguments to Mono methods 
that take a double parameter.

My actual working solution for decimals is to use an intermediate string 
representation to transfer data between Cocoa and the MONO CLR.

Your point is correct though and the class cluster nature of NSNumber makes 
things more interesting. 

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[])
{
    NSNumber *n = [NSNumber numberWithInt:5];
    NSLog(@"[[NSNumber numberWithInt:5] objCType] = %s", [n objCType]);
    NSLog(@"[@((int)5) objCType] = %s", [@((int)5) objCType]);
    NSLog(@"[@((char)5) objCType] = %s", [@((char)5) objCType]);
    NSLog(@"[@((float)5) objCType] = %s", [@((float)5) objCType]);
    
    // from NSDecimalNumber.h
    // - (const char *)objCType NS_RETURNS_INNER_POINTER;
    // return 'd' for double    
    NSDecimalNumber *dn1 = [NSDecimalNumber decimalNumberWithString:@"1.0"];
    NSLog(@"[dn1 objCType] = %s", [dn1 objCType]);
    
    NSDecimalNumber *dn2 = [NSDecimalNumber decimalNumberWithMantissa:1 
exponent:0 isNegative:NO];
    NSLog(@"[dn1 objCType] = %s", [dn2 objCType]);

    // simple subclass detection fails on a class cluster
    if ([[n class] isSubclassOfClass:[NSNumber class]]) NSLog(@"n has invalid 
subclass");
    if ([[dn1 class] isSubclassOfClass:[NSNumber class]]) NSLog(@"dn1 has 
invalid subclass");
    
    // direct subclass detection is okay
    NSLog(@"dn1 class: %@", [dn1 class]);
    
    return 0;
}

Regards

Jonathan


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to