NSMutableDictionary и добавление новых элементов KVO - PullRequest
0 голосов
/ 17 ноября 2011

Позвольте мне сначала описать мою проблему.У меня есть класс, который содержит NSMutableDictionary ivar.Существует ветка, которая будет добавлять новые пары в этот словарь - на момент написания приложения у меня не было полного списка доступных ключей.Обновленный список всех этих пар должен быть показан в табличном представлении.Я подготовил небольшое приложение для проверки концепции, в котором в xib-файле создан контроллер словарей, а его содержимое связано со словарем ivar.Проблема в том, что табличное представление показывает только начальный набор содержимого словаря.После вставки он не обновляется.

В моем доказательстве концепции приложение AppController.h выглядит следующим образом:

#import <Foundation/Foundation.h>

@interface AppController : NSObject

@property (strong) NSMutableDictionary *dictionary;

- (NSString *)randomString;
- (IBAction)addRandomPair:(id)sender;

@end

И содержимое файла реализации:

#import "AppController.h"

@implementation AppController

@synthesize dictionary = _dictionary;

- (id)init {
    self = [super init];
    if (self) {
        _dictionary = [[NSMutableDictionary alloc] init];
        [_dictionary setValue:@"Aa" forKey:@"A"];
        [_dictionary setValue:@"Bb" forKey:@"B"];
    }
    return self;
}

- (NSString *)randomString
{
    NSMutableString *aString = [[NSMutableString alloc] init];
    for (int i = 0; i < 3; i++) {
        NSUInteger r = random() % ('z' - 'a');
        [aString appendString:[NSString stringWithFormat:@"%c", ('a' +r)]];
    }
    return aString;
}

- (IBAction)addRandomPair:(id)sender
{
    [self.dictionary setValue:[self randomString] forKey:[self randomString]];
    NSLog([self.dictionary description]);
}

@end

СловарьКонтент контроллера привязан к контроллеру приложения с путем к ключу модели, установленному в «self.dictionary», а содержимое столбцов в табличном представлении привязано к контроллеру словаря с путем к ключу модели, установленному в ключ и значение соответственно.В этом приложении для подтверждения концепции нажатие кнопки добавляет новую пару (addRandomPair: action).

У меня была похожая проблема с NSMutableArray и Array Controller, но там я смог решить проблему, добавив следующую паруметоды к классу, содержащему массив ivar (именованные данные в этом классе):

- (void)insertObject:(NSString *)object inDataAtIndex:(NSUInteger)index;
- (void)removeObjectFromDataAtIndex:(NSUInteger)index;

Можно ли добавить некоторые другие методы в класс, содержащий словарь (AppController), чтобы получать уведомления о новыхвставки?Или, может быть, есть лучшее решение для моей проблемы?

Обновление

Я обнаружил, что реализация следующего набора средств доступа делает Dictionary Controller уведомленным о новом элементе:

- (void)addDictionaryObject:(NSString *)object;
- (void)removeDictionaryObject:(NSString *)object;

Проблема в том, что addDictionaryObject: имеет только один аргумент, словарь потребует что-то вроде addDictionaryObject:forKey:.Есть идеи?

Обновление 2

Я не вижу другого решения, кроме как использовать уведомление об изменении вручную - в этом случае addRandomPair: метод выглядит следующим образом:

- (IBAction)addRandomPair:(id)sender
{
    [self willChangeValueForKey:@"dictionary"];
    [self.dictionary setValue:[self randomString] forKey:[self randomString]];
    [self didChangeValueForKey:@"dictionary"];
    NSLog([self.dictionary description]);
}

Это работает, но я все еще немного не уверен, так как сам словарь не изменится, но его содержание. Правильно ли здесь использовать уведомление об изменении вручную?

Ответы [ 2 ]

4 голосов
/ 17 ноября 2011

Из документов Методы кодирования значения , только свойства NSMutableArray или NSMutableSet поддерживаются для свойств To-Many.Поскольку KVC уже работает с ключами, было бы избыточно поддерживать NSMutableDictionary, поскольку это фактически то, что setValue:forKey: уже делает.

Может быть переопределить setValue:forKeyPath:, если вы действительно хотите это за один вызов.

0 голосов
/ 17 ноября 2011

Вам нужно вызвать что-то вроде

 [_tableView reloadData];

Это скажет вашему табличному представлению существенно обновить все, что он знает.

...