如何安全地删除Observer(Swift)

时间:2015-11-19 16:18:39

标签: ios swift

我添加了一个观察者

override func viewDidLoad()
{
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector:"selector name", name: "observer name", object:nil)
    ...
}

在deinit中删除观察者时,

deinit
{
    NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
}
该应用有时崩溃

  

由于未捕获的异常'NSRangeException'而终止应用程序,原因:   '无法删除观察者“类”   对于关键路径“some string”来自   NSNotificationCenter因为它未注册为   观察者。

所以我想添加do / catch

deinit
{
    do{
        try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
    }catch{}
}

但我收到警告:

  

catch块无法访问,因为do block

中没有抛出任何错误

应用程序崩溃

当我添加试用

deinit
{
    do{
        try NSNotificationCenter.defaultCenter().removeObserver(self, forKeyPath: <some string>)
    }catch{}
}

我收到了这个警告:

  

在try expresion

中没有调用抛出函数

应用程序崩溃

应该怎么做?

2 个答案:

答案 0 :(得分:5)

如果您支持9.0版本的iOS版本,则无需在deinit方法中自行删除观察者。

取自文件

  

在OS X 10.11和iOS 9.0 NSNotificationCenter和   NSDistributedNotificationCenter将不再向其发送通知   可能被解除分配的注册观察员。

https://useyourloaf.com/blog/unregistering-nsnotificationcenter-observers-in-ios-9/

答案 1 :(得分:4)

我认为你应该使用代码

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
      @JoinColumn(name = "id_parName", referencedColumnName="parName", nullable = false),
      @JoinColumn(name = "id_description", referencedColumnName="description", nullable = false),
      @JoinColumn(name = "id_note", referencedColumnName="note", nullable = false)
    })
public DefSelfLearning getDefSelfLearning() {
    return this.defSelfLearning;
}

说明:  你在这里犯了错误:你正在使用NSNotification&amp; NSNotificationCenter所以你必须使用上面的代码来删除观察。  你有使用KVO代码删除观察者,所以它会出错。

您可以在此处阅读更多细节。 Key-Value-Observing