如何在 Swift 中传入一个 nil 通知变量
How to pass in a nil notification variable in Swift
我对 Swift 比较陌生,所以在编码时我的头脑经常 return 想到 Objective-C 解决方案。
我正在为播客播放器编写音频单元。这里面有一个自定义的 UIView 滑块和一个音频管理器单例。当通过发送通知手动更改滑块时,滑块与其父 UITableViewCell 通信,然后单元格与音频管理器通信以 play/pause 音频。
我目前正在编写代码,使音频对滑块的手动更改做出反应,为此,我将滑块上的拖动百分比发送到 Cell,以便它可以播放适当的音频。
// Notification sent containing information - notification sent from SlideView
NotificationCenter.default.post(name: Notification.Name("SlidebarManuallyMovedNotification"), object: nil, userInfo: ["percent": Double(self.getCurrentPercent())])
// Notification observed in UITableViewCell
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshCell(notification:)), name: Notification.Name("SlidebarManuallyMovedNotification"), object: nil)
通知的发送和接收工作正常:
// Some info needs to be refreshed depending on the cell state
func refreshCell(notification: NSNotification) {
// If we have user information it means we have manually changed the position so want to refresh the information
if (notification.userInfo != nil) {
... // I then run code depending on whether we have user info or not
如您所见,我收到了通知,然后移动到刷新单元格。
现在的问题来自尝试从我的 UITableViewCell 内部手动调用 refreshCell:
// 1
self.refreshCell(notification: nil)
// 2
self.refreshCell(notification: NSNotification())
// 3
let notify: NSNotification = NSNotification()
self.refreshCell(notification: notify)
我尝试了第一种方法,因为在 Objective-C 中通常很容易加载有或没有信息的不同视图 initWithCellInfo: (NSDictionary *) userInfo
。在这种情况下,我想做同样的事情,在没有任何 userInfo 的情况下调用该函数,以便我可以稍微不同地刷新我的单元格。
然后我尝试添加一个空通知,以便将其传入并且return nil userInfo。当我这样做时,我收到以下警告:
[NSConcreteNotification init]: should never be used'
这使我指向 this 答案,但我不想创建实际的通知,只是指向一个虚拟对象以调用该函数。
其他想法:
我想过创建两个函数:
func refreshCellInfo(notification: NSNotification) {
let userInfo = "foo"
self.refreshCellInfo(userInfo)
}
func refreshCellInfo(info: String) {
然后我可以调用 refreshCellInfo("")
并添加一个 if 语句来检查字符串而不是通知。
这似乎不是一种非常优雅的方法,添加了一个完全不必要的函数并捏造了 if 语句来解决问题而不是理解它。
如果有人能解释这里发生了什么,以及是否有好的解决方案,我将不胜感激,我觉得这确实突出了我理解上的差距,虽然我可能可以修补我真正想要的问题从中学习以作为开发人员前进。
您需要稍微重构一下。将接收通知的函数与刷新单元格的函数分开,然后从第一个调用第二个。
你可以这样说:
func receiveDragNotification(notification: NSNotification) {
self.refreshCellInfo(notification)
}
func refreshCellInfo(_ notification: Notification?) {
// process update
}
现在,由于通知参数在 refreshCellInfo
中是可选的,您可以根据需要传递 nil
。
但实际上,您应该进一步分离功能,这样您就有一个功能负责接收通知和更新数据模型,第二个功能负责根据数据模型更新单元格(注意你没有提供所有的细节所以我使用了一个虚构的
self.position
作为数据模型)
func receiveDragNotification(notification: NSNotification) {
// update data model based on notification
self.position = someDataFromNotification
// Now refresh the cell based on this new data
self.refreshCellInfo()
}
func refreshCellInfo() {
// use data model self.position to update cell
}
现在您可以随时调用 refreshCellInfo
,无需传递参数。
我对 Swift 比较陌生,所以在编码时我的头脑经常 return 想到 Objective-C 解决方案。
我正在为播客播放器编写音频单元。这里面有一个自定义的 UIView 滑块和一个音频管理器单例。当通过发送通知手动更改滑块时,滑块与其父 UITableViewCell 通信,然后单元格与音频管理器通信以 play/pause 音频。
我目前正在编写代码,使音频对滑块的手动更改做出反应,为此,我将滑块上的拖动百分比发送到 Cell,以便它可以播放适当的音频。
// Notification sent containing information - notification sent from SlideView
NotificationCenter.default.post(name: Notification.Name("SlidebarManuallyMovedNotification"), object: nil, userInfo: ["percent": Double(self.getCurrentPercent())])
// Notification observed in UITableViewCell
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshCell(notification:)), name: Notification.Name("SlidebarManuallyMovedNotification"), object: nil)
通知的发送和接收工作正常:
// Some info needs to be refreshed depending on the cell state
func refreshCell(notification: NSNotification) {
// If we have user information it means we have manually changed the position so want to refresh the information
if (notification.userInfo != nil) {
... // I then run code depending on whether we have user info or not
如您所见,我收到了通知,然后移动到刷新单元格。
现在的问题来自尝试从我的 UITableViewCell 内部手动调用 refreshCell:
// 1
self.refreshCell(notification: nil)
// 2
self.refreshCell(notification: NSNotification())
// 3
let notify: NSNotification = NSNotification()
self.refreshCell(notification: notify)
我尝试了第一种方法,因为在 Objective-C 中通常很容易加载有或没有信息的不同视图 initWithCellInfo: (NSDictionary *) userInfo
。在这种情况下,我想做同样的事情,在没有任何 userInfo 的情况下调用该函数,以便我可以稍微不同地刷新我的单元格。
然后我尝试添加一个空通知,以便将其传入并且return nil userInfo。当我这样做时,我收到以下警告:
[NSConcreteNotification init]: should never be used'
这使我指向 this 答案,但我不想创建实际的通知,只是指向一个虚拟对象以调用该函数。
其他想法: 我想过创建两个函数:
func refreshCellInfo(notification: NSNotification) {
let userInfo = "foo"
self.refreshCellInfo(userInfo)
}
func refreshCellInfo(info: String) {
然后我可以调用 refreshCellInfo("")
并添加一个 if 语句来检查字符串而不是通知。
这似乎不是一种非常优雅的方法,添加了一个完全不必要的函数并捏造了 if 语句来解决问题而不是理解它。
如果有人能解释这里发生了什么,以及是否有好的解决方案,我将不胜感激,我觉得这确实突出了我理解上的差距,虽然我可能可以修补我真正想要的问题从中学习以作为开发人员前进。
您需要稍微重构一下。将接收通知的函数与刷新单元格的函数分开,然后从第一个调用第二个。
你可以这样说:
func receiveDragNotification(notification: NSNotification) {
self.refreshCellInfo(notification)
}
func refreshCellInfo(_ notification: Notification?) {
// process update
}
现在,由于通知参数在 refreshCellInfo
中是可选的,您可以根据需要传递 nil
。
但实际上,您应该进一步分离功能,这样您就有一个功能负责接收通知和更新数据模型,第二个功能负责根据数据模型更新单元格(注意你没有提供所有的细节所以我使用了一个虚构的
self.position
作为数据模型)
func receiveDragNotification(notification: NSNotification) {
// update data model based on notification
self.position = someDataFromNotification
// Now refresh the cell based on this new data
self.refreshCellInfo()
}
func refreshCellInfo() {
// use data model self.position to update cell
}
现在您可以随时调用 refreshCellInfo
,无需传递参数。