Come posso convertire NSMutableArray in NSArray in Obiettivo-c?
NSArray *array = mutableArray;
Come posso convertire NSMutableArray in NSArray in Obiettivo-c?
NSArray *array = mutableArray;
Risposte:
NSArray *array = [mutableArray copy];
Copy
fa copie immutabili. Questo è abbastanza utile perché Apple può apportare varie ottimizzazioni. Ad esempio, l'invio copy
a un array immutabile conserva solo l'oggetto e restituisce self
.
Se non usi la garbage collection o ARC ricorda che -copy
conserva l'oggetto.
copy
creano un normale NSArray e non un NSMutableArray?
NSArray
& NSMutableArray
, NSString
& NSMutableString
. Ma non per esempio NSViewController
che contiene sempre uno stato mutabile.
Una NSMutableArray
è una sottoclasse di NSArray
quindi non sarà sempre necessario convertirla, ma se si desidera assicurarsi che l'array non possa essere modificato, è possibile creare NSArray
uno di questi modi a seconda che si desideri rilasciare automaticamente o meno:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
EDIT: La soluzione fornita da Georg Schölly è un modo migliore per farlo e molto più pulito, soprattutto ora che abbiamo ARC e non abbiamo nemmeno bisogno di chiamare il rilascio automatico.
Mi piacciono entrambe le 2 soluzioni principali:
NSArray *array = [NSArray arrayWithArray:mutableArray];
O
NSArray *array = [mutableArray copy];
La differenza principale che vedo in loro è come si comportano quando mutableArray è nullo :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
può essere semplificato [nil copy]
. Nell'obiettivo-c qualsiasi messaggio inviato a zero sarà sempre zero. È importante ricordare la distinzione tra "niente" e "una matrice senza niente".
prova questo codice ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
e
NSArray *myArray = [myMutableArray copy];
Di seguito è riportato il modo per convertire NSMutableArray in NSArray:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
In Swift 3.0 è disponibile un nuovo tipo di dati Array . Dichiara array utilizzando la let
parola chiave, quindi diventerà NSArray E se dichiari l'utilizzo della var
parola chiave, diventa NSMutableArray .
Codice di esempio:
let newArray = oldArray as Array
Array
s e NSArray
/ NSMutableArray
s. Non sono gli stessi.
Nell'obiettivo-c:
NSArray *myArray = [myMutableArray copy];
In breve tempo:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Questo [mutableArray copy]
antipattern è in tutto il codice di esempio. Smettere di farlo per gli array mutabili usa e getta che sono transitori e vengono deallocati alla fine dell'ambito corrente.
Non è possibile che il runtime ottimizzi la copia dispendiosa di un array mutabile che sta per uscire dall'ambito di applicazione, decrefatto su 0 e deallocato per sempre.
NSMutableArray
a una NSArray
variabile non la convertirà (che è la domanda del PO). L'esposizione di tale valore (ad esempio come valore restituito o come proprietà) potrebbe comportare problemi molto difficili da eseguire il debug se tale valore è stato inaspettatamente mutato. Questo vale sia per le mutazioni interne che esterne poiché il valore mutabile è condiviso.
NSMutableArray
variabile è sufficiente. Dato che l'oggetto non ha mai smesso di essere un array mutabile, la chiamata a metodi di muting su di esso avrà successo e trasformerà i dati condivisi. Se d'altra parte l'array mutabile originale fosse copiato - cambiandolo in un array immutabile - e quindi assegnato a una NSMutableArray
variabile e avessero richiamato metodi di muting, quelle chiamate fallirebbero con doesNotRespondToSelector
errori perché l'oggetto che ha ricevuto la chiamata del metodo mutating è in fatto immutabile e non risponde a questi metodi.
Se stai costruendo un array tramite la mutabilità e vuoi restituire una versione immutabile, puoi semplicemente restituire l'array mutabile come "NSArray" tramite l'ereditarietà.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Se "ti fidi" del chiamante per trattare l'oggetto restituito (tecnicamente ancora mutabile) come un NSArray immutabile, questa è un'opzione più economica di [mutableArray copy]
.
Per determinare se è possibile modificare un oggetto ricevuto, il destinatario di un messaggio deve fare affidamento sul tipo formale del valore restituito. Se riceve, ad esempio, un oggetto array digitato come immutabile, non dovrebbe tentare di mutarlo . Non è una pratica di programmazione accettabile determinare se un oggetto è mutabile in base alla sua appartenenza alla classe.
La pratica di cui sopra è discussa in modo più dettagliato qui:
Procedura consigliata: restituire mutableArray.copy o mutableArray se il tipo restituito è NSArray
NSArray *array = [mutableArray copy];