Как получить доступ к объекту NSDocument из другого объекта, хранящегося в NSMutableArray?

Это действительно расширение Как показать рассчитанные значения в NSTableView?

Проблема:

У меня есть класс NSDocument, который содержит два свойства: text (NSString) и phrases (NSMutableArray NSObjects с NSString в них). В файле Doc NIB у меня есть TextView (для отображения фраз) с двумя столбцами. Первый столбец привязан к ArrayController и отображает NSString. Это работает нормально. Я хочу подсчитать количество вхождений NSString в text и отобразить это во втором столбце.

Что я пробовал:

Определите статическую переменную в моем NSObject, которая указывала бы на TextView. После загрузки NIB он установит эту статическую переменную в TextView, содержащую строку text.

Это работает нормально, если я открываю одно окно. Но если я попытаюсь открыть несколько окон, статический var будет обновлен новыми экземплярами TextView (из других окон). Понятно, что это все ломает.

Вопрос:

Как получить доступ к text из каждого NSObject? Другими словами, диаграмма объектов NSDocument --(содержит один) --> NSMutableArray --(содержит несколько) --> NSObject, так как же мне добраться до NSDocument из NSObject?


person rytis    schedule 09.10.2011    source источник


Ответы (1)


Вместо массива строк используйте массив словарей:

    NSDictionary *entry = [NSDictionary dictionaryWithObjectsAndKeys:
                                          thePhrase, @"phrase",
                                          theCount, @"count",
                                          nil];
    [theArray addObject:entry];

Привязать к arrangedObjects.phrase и arrangedObjects.count.

В качестве альтернативы вы можете создать класс Phrase, содержащий фразу, ссылку на документ и код для подсчета количества.

person paulmelnikow    schedule 10.10.2011
comment
ну, у меня уже есть собственный класс, в котором есть NSstring. Мне просто было трудно назначать ему документ каждый раз, когда он создается (пользователь вставляет новую запись или документ загружается). У меня есть код, который делает это в двух местах: WindowDidLoad выполняет итерацию по всем объектам Phrase и присваивает TextView каждому. И в insertObject у меня есть похожее действие, которое присваивает TextView каждому новому объекту. Это работает, но просто кажется неправильным. Поэтому мне было интересно, есть ли более элегантное решение. - person rytis; 11.10.2011
comment
Вместо того, чтобы фраза знала о текстовом представлении, дайте ей знать о документе и запросите у документа его текст. И вы можете установить указатель документа фразы в Phrase -init вместо windowDidLoad. Для получения дополнительной информации о тех вопросах, которые вы задаете, взгляните на шаблон Model-View-Controller: developer.apple.com/library/mac/#documentation/cocoa/conceptual/ - person paulmelnikow; 11.10.2011
comment
да, это имеет смысл. Я пробовал это, но почему-то мне не удалось получить доступ к NSString, который был (до сих пор) привязан к NSTextView. Я думаю, проблема в том, что я использую неправильный тип здесь. После загрузки из файла фактический объект не является NSString (gdb говорит, что это NSConcreteMutableData). С TextView все в порядке, но не с моим методом поиска, который ожидает строку. atm я использую [textview string], чтобы добраться до него, но я полагаю, что здесь мне нужно привязаться к другому типу. - person rytis; 11.10.2011
comment
Понятно. Как вы загружаете файл сейчас? Вы можете попробовать NSString *string = [NSKeyedUnarchiver unarchiveObjectWithData:dataObject] - person paulmelnikow; 11.10.2011
comment
Вот что я делаю сейчас: - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { NSKeyedUnarchiver *unarchiver; unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [self setPhrases:[unarchiver decodeObjectForKey:@"phrases"]]; [self setExcerptText:[unarchiver decodeObjectForKey:@"excerptText"]]; [unarchiver finishDecoding]; [unarchiver release]; return YES; } - person rytis; 11.10.2011
comment
так же как: NSKeyedArchiver *archiver; NSMutableData *data = [NSMutableData data]; archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [archiver encodeObject:[self excerptText] forKey:@"excerptText"]; [archiver encodeObject:[self phrases] forKey:@"phrases"]; [archiver finishEncoding]; [archiver release]; return data; - person rytis; 11.10.2011
comment
Попробуйте записать [self excerptText] перед сохранением. Вероятно, это NSMutableData вместо NSMutableString. - person paulmelnikow; 11.10.2011
comment
Да, кажется, я получаю CLASS: NSConcreteMutableData, если я регистрирую [excerptText class]. Какой тип лучше всего использовать с NSTextView? Я наивно предположил NSString, но теперь, оглядываясь вокруг, кажется, что это не лучший выбор, должны ли это быть изменяемые данные? в документе Apple они используют NSAttributedString. - person rytis; 11.10.2011
comment
ааа, мне действительно нужно больше читать. Нашел этот pseudofish.com/blog/2005/06/15 /binding-to-nstextview. Затем понял, что значение в NSTextView на самом деле имеет 4 варианта. И тот, который я выбрал (не знаю, почему), был Data, поэтому excerptText был установлен в NSConcreteMutableData при загрузке! - person rytis; 12.10.2011
comment
Таким образом, текстовое представление читало строку, превращало ее в данные, а затем заменяло строку данными. Потрясающий. - person paulmelnikow; 12.10.2011