2014-07-13 10 views
11

Ora che gli array di Swift sono veramente immutabili grazie alla semantica a valore pieno, come posso creare una copia mutabile di un array immutabile? Simile a Obj-C mutableCopy(). Ovviamente posso ridimensionare l'array su un NSArray e usare mutableCopy() ma non voglio usare NSArray perché non è stato scritto a dovere.Come si crea una copia mutevole di un array immutabile in rapido?

Ho uno toolbar che ha items dallo storyboard. Voglio rimuovere un elemento dalla barra degli strumenti e utilizzare toolbar.setItems. Volevo farlo senza casting come NSArray, perché nessuna di queste funzioni ha il valore NSArrays, esse prendono [AnyObject].

Ovviamente ora quando chiamo removeAtIndex() non funziona, che è corretto. Ho solo bisogno di un mutableCopy

semplicemente assegnando ad var non funziona per me e dare 'Immutable value of type [AnyObject]'

var toolbarItems = self.toolbar.items 
toolbarItems.removeAtIndex(2) //Immutable value of type [AnyObject] 

Sto usando Beta 3

risposta

18

Il problema è che self.toolbar.items è un implicito scartare opzionale (di tipo [ANYOBJECT]!) E sono sempre immutabili Quando si assegna alla variabile toolbarItems senza specificare esplicitamente il suo tipo, anche questo diventa facoltativo da scartare implicitamente, e quindi anche immutabile.

Per correggere questo fare uno:

var toolbarItems:[AnyObject] = self.toolbar.items 
toolbarItems.removeAtIndex(2) 

Oppure:

var toolbarItems = self.toolbar.items as [AnyObject] 
toolbarItems.removeAtIndex(2) 

Aggiornamento

Come di Xcode 6 Beta 5, è possibile aggiornare le collezioni che sono memorizzati in variabili facoltative , quindi il codice originale ora funziona:

var toolbarItems = self.toolbar.items 
toolbarItems.removeAtIndex(2) 
+0

Questo è praticamente quello che ho detto nella mia risposta, ma con una spiegazione concisa di ciò che è sotto il cofano - quindi ti meriti il ​​mio upvote – Antonio

11

Gli array sono tipi di valore (struct), in modo che siano passato per valore e non per riferimento.

Detto questo, se si crea una variabile di tipo array e gli si assegna l'array immutabile, una copia della matrice immutabile viene effettivamente creata e assegnata ad essa - e ovviamente quella copia non ha alcuna relazione con l'array immutabile originale (oltre ad avere gli stessi valori nel momento in cui viene creato).

let immutable = [1, 2, 3] 

//immutable[0] = 1 // Fails, ok 

var mutable = immutable 

mutable[0] = 5 

Nel tuo caso, si accede a una serie immutabile, che è un NSArray di AnyObject s (vedi documentation). È possibile utilizzarlo come un array in rapido, fare una copia di esso e modificare nel modo seguente:

let immutable : NSArray = [ 1, 2, 3 ] 

//immutable[0] = 1 // Fails, ok 

var mutable : [AnyObject] = immutable 

mutable.removeAtIndex(1) // mutable now is [1, 3] 

mutable[0] = 7 // mutable now is [7, 3] 

Dopo aver finito con le modifiche, è possibile assegnare alla proprietà items

+0

Questo non funziona per me, penso a causa della beta 3 ?: 'var = toolbarItems self.toolbar.items; toolbarItems.removeAtIndex (2)' '// valore immutabile di tipo '[ANYOBJECT]' Aggiunto Modifica alla domanda. – Johnston

+0

Penso che il problema sia dovuto al fatto che 'self.toolbar.items' è un' NSArray'. Guardandolo – Antonio

+0

Forse con un NSArray, devi andare un po 'più alla vecchia scuola? Prova 'var mutable = immutable.mutableCopy() come NSMutableArray'? –

1

È come semplice come dichiarare un var con l'array.

var items = toolbar.items 

Ora è possibile modificare le voci e quindi riassegnare alla barra degli strumenti.

toolbar.items = items 

Si noti che è possibile non può (a partire da Beta 3) modificare gli elementi di un array "immutabile" dichiarato con let pure. La lunghezza dell'array è corretta, motivo per cui non è possibile rimuovere gli elementi.

Tuttavia, in base alla documentazione di Apple UIToolbar, l'array items è già modificabile.

SWIFT
var items: [AnyObject]!

+0

Vedere la mia modifica. Non sono sicuro se questo è dovuto alla Beta 3? – Johnston

+0

La tua ultima modifica (con 'var b = a') funziona perfettamente con Xcode build 6A254o. Se provi 'a [1] = 5' vedrai che' b' è alterato come previsto. – Mundi

+0

yah I am dumbo non intendevo scriverlo. L'ho rimosso. Questo funziona, ma per qualche motivo 'self.toolbar.items 'è ancora immutabile. E penso che gli array ora siano completamente immutabili se li assegni. Dalle note di rilascio di Apple: "Array in Swift è stato completamente ridisegnato per avere semantica a valore pieno come il dizionario e la stringa hanno sempre avuto in Swift. Questo risolve vari problemi di mutevolezza - ora un array 'let' è completamente immutabile e un ' var 'array è completamente modificabile " – Johnston

0

In Beta3 array costanti sono completamente immutabili mentre array variabili sono interamente mutevole.Quindi, basta cambiare lasciare array: a matrice di var: e quindi verificare il codice

1

Provato + funziona:

var mutable : [UIBarButtonItem] = [] 
    for button in toolbar.items { 
     mutable += button as UIBarButtonItem 
    } 
    mutable.removeAtIndex(2) 
    toolbar.setItems(mutable, animated: true) 
1

PER RIMUOVERE UN OGGETTO DALL'INDICE PARTICOLARE DI UN ARRAY.

let fullArray : NSArray = Userdefaults().value(forKey: "YOUR_ARRAY_STRING") as! NSArray 
var mutableArray : [AnyObject] = fullArray as [AnyObject] 
mutableArray.remove(at: INDEX_TO_REMOVE) //Eg: mutableArray.remove(at: 0) 
mutableArray.append(ARRAY_TO_APPEND) 
Problemi correlati