#macos #cocoa #swift #nstableview #nsnotificationcenter
#macos #какао #swift #nstableview #nsnotificationcenter
Вопрос:
Я получил очень странное поведение при перезагрузке данных NSTableView внутри notification observer.
class MainWindowController: NSWindowController, NSTableViewDataSource, NSTableViewDelegate
{
var data: String[] = []
@IBOutlet var filesTableView: NSTableView!
override func awakeFromNib()
{
super.awakeFromNib()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "droppedFiles:", name: DroppedFilesNotification.notificationName, object: nil)
}
func droppedFiles(notification: NSNotification!)
{
data = ["123"]
println(data.count)
filesTableView.reloadData()
}
func numberOfRowsInTableView(tableView: NSTableView!) -> Int
{
return data.count
}
@IBAction func crazyTest(AnyObject)
{
NSNotificationCenter.defaultCenter().postNotificationName(DroppedFilesNotification.notificationName, object: self, userInfo: [DroppedFilesNotification.fileNamesParameterName: ["123"]])
}
}
Отображается первый вызов функции crazyTest:
1
Отображается секундный вызов функции crazyTest:
2
3
4
Третий вызов функции crazyTest отображает числа 5-13.
Если бы мы удалили filesTableView.reloadData() из функции droppedFiles, тогда все работает нормально, за исключением того, что представление таблицы не обновляется. Есть идеи, почему это происходит и как перезагрузить там табличное представление?
Редактировать:
Кроме того, нет проблем в случае, если вызов функции droppedFiles напрямую вместо использования NSNotificationCenter. Но я бы предпочел использовать центр уведомлений в своем приложении.
Заранее спасибо.
Ответ №1:
Если это табличное представление на основе представления, которое (возможно, неявно) загружает свои представления из NIBS, то его awakeFromNib
метод будет вызываться каждый раз при загрузке NIB. Отсюда:
Примечание: Вызов
makeViewWithIdentifier:owner:
приводитawakeFromNib
к многократному вызову вашего приложения. Это происходит потомуmakeViewWithIdentifier:owner:
, что загружается перо с переданным владельцем, и владелец также получаетawakeFromNib
вызов, даже если он уже активирован.
В вашем случае вы каждый раз регистрируетесь для получения уведомления. Итак, вы регистрируетесь для этого много раз и получаете уведомление один раз за каждую регистрацию.
Комментарии:
1. Спасибо, Кен! Я не знаю, как пропустил эту заметку 😉
Ответ №2:
Вы не удаляете наблюдателя. Я предполагаю, что вы входите в этот контроллер представления несколько раз, и поэтому он регистрируется для одного и того же уведомления несколько раз. Поэтому при запуске уведомлений обратный вызов вызывается несколько раз.