2015-04-05 76 views
0

我怎麼能真正同步NSMutableArray與NSArrayController?排序在NSArrayController

我在我的UI中有類Dialog和NSArrayController,它將Content Array綁定到Dialog.messages。當我直接在Dialog.messages增加任何新項目,他們也在NSArrayController的提供,一切看起來不錯:

[Dialog addMessage: someMsgItem]; 

但我也需要對郵件進行排序和它僅適用於Dialog.messages而不是NSArrayController的:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey: @"timestamp" ascending: YES]; 
_messages = [NSMutableArray arrayWithArray: [_messages sortedArrayUsingDescriptors: @[sort]]]; 

如何使這些更改也適用於我的NSArrayController?這是Dialog類實現的一部分:

@implementation Dialog 
@synthesize messages = _messages; // NSMutableArray 

- (void) addMessage:(Message *)msg { 
    [self insertObject:msg inMessagesAtIndex:[_messages count]]; 
} 

- (void) removeMessage:(Message *)msg { 
    [self removeObjectFromMessagesAtIndex:[self.messages indexOfObject:msg]]; 
} 

- (NSArray *) messages { 
    return [_messages copy]; 
} 

- (void) setMessages:(NSArray *)messages { 
    [self willChangeValueForKey:@"messages"]; 
    _messages = [NSMutableArray arrayWithArray:messages]; 
    [self didChangeValueForKey:@"messages"]; 
} 

- (void) insertObject:(Message *)msg inMessagesAtIndex:(NSUInteger)index { 
    [_messages insertObject:msg atIndex:index]; 
} 

- (void) removeObjectFromMessagesAtIndex:(NSUInteger)index { 
    [_messages removeObjectAtIndex:index]; 
} 
@end 

回答

2

您不需要對_messages數組進行排序。在陣列控制器上設置sortDescriptors,其arrangedObjects將根據這些描述符進行排序。然後,無論UI(表格視圖?)綁定到陣列控制器的arrangedObjects將自動獲取排序順序。

複雜的是,當您需要查找與UI元素對應的模型對象(例如表格視圖中的行)時,您需要索引到陣列控制器的arrangedObjects而不是_messages

如果你真的想排序_messages

  1. 並沒有取代它像你顯示的代碼。可變數組可以排序,如[someMutableArray sortUsingDescriptors:@[sort]]

  2. 你必須確保,當你改變以外_messages通過調用的KVO兼容存取方法之一志願更改通知發出。有兩種方法可以做到這一點:

    a。致電-willChangeValueForKey:-didChangeValueForKey:。例如:

    [self willChangeValueForKey:@"messages"]; 
    [_messages sortUsingDescriptors:@[sort]]; 
    [self didChangeValueForKey:@"messages"]; 
    

    我不推薦這個選項。這很容易出錯,並且肯定會產生效率最低的更改通知。

    b。操作從-mutableArrayValueForKey:返回的類似於可變數組的代理。例如:

    [[self mutableArrayValueForKey:@"messages"] sortUsingDescriptors:@[sort]]; 
    

    有至少的機會,這將產生更有效的變更通知(與NSKeyValueChangeKindKeyNSKeyValueChangeReplacement)。

順便說一句,你需要調用-willChangeValueForKey:-didChangeValueForKey:-setMessages:方法,事實上,你不應該。由於該方法符合名爲「消息」的屬性設置者的常規命名約定,因此KVO會自動掛鉤並生成適當的更改通知。 (如果你不想這樣做,你將不得不重寫+automaticallyNotifiesObserversForKey:來爲該鍵返回false。)

+0

我把它用於NSCollectionView,但認爲沒關係。謝謝你的建議,這比我想象的要容易得多。這種NSArrayController實例完美工作: '[nsArrayControllerItem setSortDescriptors:@ [[NSSortDescriptor sortDescriptorWithKey:@「timestamp」ascending:YES]]];' – 2015-04-05 11:11:05