Табличное представление не обновляется в соответствии с привязками

Это вопрос для новичков, и я делал это много раз раньше, но на этот раз я кое-что упустил.

В моем файле AppDelegate.h я объявляю NSArray и устанавливаю его как свойство:

@interface AppDelegate : NSObject {
NSArray *lines;

}

@property(readwrite, retain) NSArray *lines;
@end

А затем в файле AppDelegate.m в методе awakeFromNib я размещаю его:

lines = [[NSArray alloc] init];

Затем у меня есть метод, который устанавливает массив строк:

NSString *fileContents = [NSString stringWithContentsOfFile:[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/sometextfile.txt"] encoding:NSUTF8StringEncoding error:NULL];
lines = [fileContents componentsSeparatedByString:@"\n"];

У меня есть контроллер массива, привязанный к AppDelegate.self.lines, тогда у меня есть столбец таблицы, привязанный к Array Controller.arrangedObjects. Я могу подтвердить, что массив обновляется (тестируется с помощью NSLog), однако содержимое таблицы не обновляется (оно остается пустым).

Есть что-то очевидное, что мне здесь не хватает?


person indragie    schedule 26.08.2009    source источник
comment
Не делай error:NULL. Есть ряд вещей, которые могут пойти не так в этом утверждении, и вы не хотите знать, что именно произошло.   -  person Peter Hosey    schedule 27.08.2009


Ответы (3)


Если вы используете привязки, вам не нужен источник данных. Один или другой.

У меня есть контроллер массива, который привязан к «AppDelegate.self.lines»…

Почему self?

@property (чтение, запись, сохранение) NSArray * lines;

Нет, используйте здесь copy. В противном случае вы обнаружите, что сохраняете чей-то изменяемый массив, который затем они будут видоизменять. Тогда «ваш» массив изменится без вашего ведома.

Затем у меня есть метод, который устанавливает массив строк:

lines = [fileContents componentsSeparatedByString:@"\n"];

Поэтому в таблице ничего не отображается. Вы не просматриваете свойство, вы напрямую обращаетесь к переменной экземпляра. Прямой доступ к переменной экземпляра не вызывает уведомлений KVO, поэтому контроллер массива никогда не узнает об изменении.

Хуже того, вы пропускаете старый массив (поскольку вы просто назначаете его, не освобождая его) и недостаточно сохраняете этот новый массив. Поскольку вы не сохраняете новый массив, эта переменная экземпляра вскоре будет содержать мертвый объект. Автоматическое сохранение выполняется методом setLines:, который вызывается только тогда, когда вы его вызываете.

Вам необходимо пройти по собственности:

self.lines = [fileContents componentsSeparatedByString:@"\n"];

Доступ к свойству - это неявное сообщение доступа, поэтому оно как сохраняет массив (или копирует его, как только вы исправляете @property, как я предложил выше), так и отправляет уведомления KVO.

person Peter Hosey    schedule 26.08.2009

Когда вы говорите, что у вас есть объекты, привязанные к столбцу, вы имеете в виду, что устанавливаете источник данных tablview? Если вы не установите источник данных tableview в массив строк

person ennuikiller    schedule 26.08.2009
comment
Хорошо, у меня есть контроллер массива, для массива содержимого которого задано значение AppDelegate.self.lines. Затем я привязываю объекты Array Controller к столбцу таблицы. Я не установил dataSource для t, мне это нужно? - person indragie; 26.08.2009
comment
ennuikiller: Привязки - альтернатива источникам данных. - person Peter Hosey; 26.08.2009

Возможно, вы захотите прочитать это, у него есть хорошие схемы и пояснения. То, что говорит ennuikiller, правильно, я думаю, это проблема с вашим источником данных. Это делается путем вызова

[aTable setDelegate:aDelegate];
person slf    schedule 26.08.2009
comment
Я попытался установить источник данных / делегат как для основного делегата приложения, так и для контроллера массива, ни один из них не работал. - person indragie; 26.08.2009