2016-04-23 13 views
7

Proprio come dice il titolo. Ho dovuto memorizzare Int64 nel NSUserDefaults e l'unico modo che ho trovato per farlo era immagazzinarla come NSNumber comeCome convertire/trasmettere NSNumber in Int64?

NSNumber(longLong: someInt64) 

ma non so come convertire di nuovo a Int64.

+4

Un po 'di [lettura della documentazione] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/ # // apple_ref/occ/instp/NSNumber/longLongValue) può fare molto. – nhgrif

+0

Stavo guardando quella pagina e o non l'ho visto o non l'ho capito. In effetti non sono sicuro di averlo capito ora. Ok, sono stupido, sei tutto intelligente, sei felice? – TimSim

+0

Quale parte non capisci? Leggere la documentazione è una parte cruciale dell'essere uno sviluppatore, quindi se c'è qualcosa che non comprendi, mi piacerebbe aiutarti a capirlo (cosa che realizzerai ti farà risparmiare tempo a lungo termine). – nhgrif

risposta

16

TL; DR

Utilizzare la proprietà di NSNumberint64Value per recuperare il valore Int64:

let someInt64: Int64 = 314 

let n = NSNumber(value: someInt64) 

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

lungo risposta

NSNumber è a differenza di tipi primitivi tali come Int e Double. NSNumber è una classe che viene da Foundation, che è stata progettata attorno all'obiettivo C e alle sue limitazioni. NSNumber funge da wrapper di oggetti per tipi primitivi (come Int, Double e Bool) che non sono oggetti.

In Objective-C, gli oggetti sono memorizzati in NSArray e NSDictionary, ma questi possono solo contenere oggetti (ad esempio istanze di classi). I tipi primitivi come Int, Double e Bool non sono oggetti. I progettisti di Objective-C hanno avuto un problema; non sarebbe molto utile se non fosse possibile inserire interi o doppi in array e dizionari. La soluzione era di avvolgere questi tipi primitivi in ​​una classe chiamata NSNumber.

Originariamente in Objective-C, NSNumbers sono stati creati con costruttori come:

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

Quando sono state aggiunte moderna dispone di Objective-C, è stato possibile creare in modo più semplice:

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

Una volta ottenuto uno NSNumber, è possibile estrarre il valore contenuto chiamando la proprietà appropriata:

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

// Swift 
let d = n.doubleValue 

Swift ha la capacità di creare NSNumber al volo quando si assegna un tipo primitivo (Int, Double, Bool, ecc) per una variabile di tipo NSNumber. Ciò è stato fatto per semplificare la chiamata alle API Cocoa e Cocoa Touch da Swift senza dover includere esplicitamente tipi primitivi (che sarebbero stati dolorosi).

// 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)) 

La cosa strana NSNumber è che si può mettere in un tipo e recuperare un altro:

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

per cui spetta al programma per tenere traccia di ciò che è in là.

Quindi, se avete un NSNumber e desidera che il valore contenuto all'interno come Int64, è necessario accedere con la proprietà int64Value:

let n = NSNumber(value: someInt64) 
let m = n.int64Value // m is an `Int64` 
+0

Grazie amico, dovrebbero portarti a scrivere i documenti. Il fatto è che ho letto la tua spiegazione, posso capire anche quella parte dei documenti ufficiali. Ciò che mi ha confuso e buttato fuori in questo caso era che potevo fare 'Double (someNSNumber)' o 'Int (someNSNumber)' ma non 'Int64 (someNSNumber)'. – TimSim

+0

'longLongValue' è stato rinominato in 'int64Value' –

+0

Grazie a @RadekWilczak! Ho aggiornato la risposta. – vacawama

1

SWIFT 3

Un esempio per la memorizzazione e recuperando le proprietà per millisecondi. Può essere utilizzato per qualsiasi Int64 oggetto:

fileprivate static let TIME = "TIME" 
public static var time: Int64 { 
     get { 
      if let obj = UserDefaults.standard.object(forKey: TIME), let t = obj as? NSNumber { 
       return t.int64Value 
      } 
       return Int64(Date().timeIntervalSince1970 * 1000.0) 
     } 
     set(v) { 
      UserDefaults.standard.set(NSNumber(value: v), forKey: TIME) 
     } 
    }