Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert/cast NSNumber to Int64?

Tags:

swift

Just like the title says. I had to store Int64 in NSUserDefaults and the only way I found to do that was storing it as NSNumber like

NSNumber(longLong: someInt64)

but I don't know how to convert it back to Int64.

like image 623
TimSim Avatar asked Apr 23 '16 20:04

TimSim


1 Answers

TL;DR

Use the int64Value property of NSNumber to retrieve the Int64 value:

let someInt64: Int64 = 314

let n = NSNumber(value: someInt64)

let m = n.int64Value  // m is an `Int64`

Long Answer

NSNumber is unlike primitive types such as Int and Double. NSNumber is a class that comes from Foundation, which was designed around Objective-C and its limitations. NSNumber serves as an object wrapper for primitive types (such as Int, Double, and Bool) which are not objects.

In Objective-C, objects are stored in NSArray and NSDictionary, but these can only hold objects (i.e. instances of classes). Primitive types such as Int, Double, and Bool are not objects. The designers of Objective-C had a problem; it wouldn't be very useful if you couldn't put integers or doubles in arrays and dictionaries. The solution was to wrap these primitive types in a class called NSNumber.

Originally in Objective-C, NSNumbers were created with constructors such as:

// Objective-C
NSNumber *n = [NSNumber numberWithDouble: 3.14];
NSNumber *b = [NSNumber numberWithBool: YES];

When Modern Objective-C features were added, it became possible to create them more simply:

// Modern Objective-C
NSNumber *n = @3.14;
NSNumber *b = @YES;

Once you have an NSNumber, you can extract the contained value by calling the appropriate property:

// Objective-C
double d = [n doubleValue];     // method call notation
double d = n.doubleValue;       // dot notation

// Swift
let d = n.doubleValue

Swift has the ability of creating NSNumber on the fly when assigning a primitive type (Int, Double, Bool, etc.) to a variable of type NSNumber. This was done to make it easy to call Cocoa and Cocoa Touch APIs from Swift without having to explicitly wrap primitive types (which would have been painful).

// In Swift
let n: NSNumber = 3.14    // No need to do let n = NSNumber(double: 3.14)

let a = NSMutableArray()
a.addObject(3.14)         // No need for a.addObject(NSNumber(double: 3.14))
a.addObject(true)         // No need for a.addObject(NSNumber(bool: true))

The weird thing about NSNumber is that you can put in one type and retrieve another:

// In Swift
let n: NSNumber = 3.14
let truth = n.boolValue
print(truth)   // "true"

so it is up to the program to keep track of what is in there.

So, if you have an NSNumber and want the value contained within as an Int64, you need to access it with the int64Value property:

let n = NSNumber(value: someInt64)
let m = n.int64Value  // m is an `Int64`
like image 65
vacawama Avatar answered Sep 20 '22 00:09

vacawama