2009-03-14 8 views
7

Sto utilizzando uno NSArrayController, NSMutableArray e NSTableView per mostrare un elenco di oggetti personalizzati (sebbene questa domanda probabilmente si applica se si sta solo visualizzando un elenco di oggetti vaniglia NSString).Come rimuovere tutti gli elementi da un NSTableView controllato da NSArrayController?

In vari punti nel tempo, ho bisogno di cancellare la mia matrice e aggiornare i dati dalla mia fonte di dati. Tuttavia, chiamare semplicemente removeAllObjects sull'oggetto NSMutableArray non attiva gli aggiornamenti KVO, pertanto l'elenco sullo schermo rimane invariato.

NSArrayController ha noremoveAllObjects metodo disponibile, che sembra davvero strano. (Esso ha addObject, che io uso per aggiungere gli oggetti, garantendo la KVO viene attivato e l'interfaccia utente è aggiornato.)

Il modo più pulito sono riuscito a causare questo accada correttamente è:

[self willChangeValueForKey:@"myArray"]; 
[myArray removeAllObjects]; 
[self didChangeValueForKey:@"myArray"]; 

... così sto tipo di dover fare la notifica KVO manualmente me stesso (questo è nel mio test di classe app, che contiene la proprietà myArray, che è NSMutableArray, come detto.)

questo sembra sbagliato - è c'è un modo migliore? Dal mio googling sembra che alcune persone siano confuse dalla mancanza di removeAllObjects in NSArrayController, ma non hanno visto soluzioni migliori.

ho visto questa soluzione:

[self removeObjectsAtArrangedObjectIndexes: 
    [NSIndexSet indexSetWithIndexesInRange: 
    NSMakeRange(0, [[self arrangedObjects] count])]]; 

ma questo sembra ancora più spiacevole per me. Almeno la mia soluzione è almeno marginalmente autodocumentante.

Apple non ha notato che a volte le persone potrebbero voler svuotare un controllo elenco gestito tramite un oggetto NSArrayController? Questo mi sembra ovvio, quindi penso che mi debba mancare qualcosa ...

A parte: ovviamente, se aggiungo nuovi elementi all'array (tramite NSArrayController), questo innesca un aggiornamento KVO con lo NSArrayController/NSTableView, ma :

  1. A volte non inserisco alcun elemento nell'elenco, perché non ce ne sono. Quindi vedi solo i vecchi oggetti.
  2. Questo è comunque un po 'schifo.

risposta

16

Non rimuovere elementi da una vista tabella. Non ha alcun oggetto: mostra solo gli oggetti di un altro oggetto.

Se si associa il binding dell'array del contenuto dell'array del controller a una proprietà di matrice di qualche altro oggetto, si dovrebbe lavorare con quella proprietà di tale oggetto. Utilizzare [[object mutableArrayValueForKey:@"property"] removeAllObjects].

Se, d'altra parte, non si è vincolato il binding del contenuto dell'array del controller dell'array, è necessario interagire direttamente con lo content. Utilizzare [[arrayController mutableArrayValueForKey:@"content"] removeAllObjects]. (Si potrebbe anche lavorare con arrangedObjects invece di content. Se uno non funziona, prova l'altro: ho sempre fatto cose solo nel primo modo, legando il controller di array a qualcos'altro.)

+0

Grazie - funziona. Ho cambiato il mio codice originale nella mia domanda a: [[self mutableArrayValueForKey: @ "myArray"] removeAllObjects]; e funziona perfettamente. Molto più pulito Hai scritto mutableArrayValueForKey errato btw - risolvilo e lo contrassegnerò come risposta accettata. :-) – Slacker

+3

Il tuo metodo funziona perfettamente quando ArrayController è limitato a un array. Ma non funziona quando ArrayController non è limitato a un array. L'array 'content' che si ottiene da ArrayController è un' NSArray' non 'NSMutableArray'. Basta usare il metodo di ArrayController per cancellare il contenuto: 'NSRange range = NSMakeRange (0, [[anArrayController arrangedObjects] count]); [anArrayController removeObjectsAtArrangedObjectIndexes: [NSIndexSet indexSetWithIndexesInRange: range]];' – Quincy

+2

@Quincy '' 'NSRange'' 'soluzione è significativamente più veloce della risposta originale o' '' [anArrayController removeObjects: [anArrayController arrangedObjects]] '' '. Grazie! – bdunagan

3

avuto questo problema come bene e risolto in questo modo:

NSArrayController* persons = /* your array controller */; 
[[persons content] removeAllObjects]; 
+1

Sfortunatamente, questo non funziona. Se si dovessero chiamare [persone disposte in Object], il contenuto dell'array potrebbe ancora essere lì. Dopo aver rimosso tutti gli elementi dall'array di contenuti con removeAllObjects, ho scoperto che è necessario chiamare anche [persone riorganizzaoggetti]. – ericg

+0

il mio programma si arresta in modo anomalo con questo ... – TCB13

0

Soluzione in Swift:

if let ac = arrayController 
{ 
    let range:NSRange = NSMakeRange(0, ac.arrangedObjects.count); 
    let indexSet:NSIndexSet = NSIndexSet(indexesInRange: range); 
    ac.removeObjectsAtArrangedObjectIndexes(indexSet); 
} 
1

Swift

@IBOutlet var acLogs: NSArrayController! 

acLogs.removeObjects(acLogs.content as! [AnyObject]) 

ha lavorato per me.

Problemi correlati