如何使用 addObserver 闭包方法在 Swift 5 中删除Observer

2024-02-17

这是我的第一篇文章。 我是日本 iOS 工程师(这个月刚入职)。

我有一个麻烦removeObserver的方法NotificationCenter在 Swift 5 中。

我通过使用闭包类型将观察者添加到 ViewController (VC)addObserver。 我想在 VC 的去初始化调用时删除这个观察者。

I wrote NotificationCenter.default.removeObserver(self)在VC中deinit方法。但是,这似乎对我不起作用。

有什么问题???

此外,如果我的代码存在内存泄漏问题,请告诉我如何修复它。

这是我的一段代码。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] notification in

            guard let self = self else { return }
            self.loadWeather(notification.object)
        }
    }
    
    deinit {
        print(#function)
        print("ViewController died")

        NotificationCenter.default.removeObserver(self)
    }
}

基于闭包的addObserver https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver

如果您使用基于闭包的addObserver 的变体,token (not self) 是 观察者。通知中心根本不知道self在这个情况下。该文档不是很清楚 这。

from Twitter https://twitter.com/olebegemann/status/1253006445295042565?s=20

这意味着这样做毫无意义:NotificationCenter.default.removeObserver(self)

The docs https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver推荐两种方式:

正常方式

像平常一样订阅:

let center = NSNotificationCenter.defaultCenter()
let mainQueue = NSOperationQueue.mainQueue()
self.localeChangeObserver = center.addObserverForName(NSCurrentLocaleDidChangeNotification, object: nil, queue: mainQueue) { (note) in
    print("The user's locale changed to: \(NSLocale.currentLocale().localeIdentifier)")
}

在代码的某个点删除观察者。NotificationCenter.default.removeObserver(self.localeChangeObserver)例如通过函数或在deinit

注意:您仍然需要使用[weak self]以避免循环引用。

为了避免循环引用,请使用弱引用self当在块内时self包含观察者作为强参考。

单一订阅

第一次收到回调后立即删除观察者

let center = NSNotificationCenter.defaultCenter()
let mainQueue = NSOperationQueue.mainQueue()
var token: NSObjectProtocol?
token = center.addObserverForName("OneTimeNotification", object: nil, queue: mainQueue) { (note) in
    print("Received the notification!")
    center.removeObserver(token!)
}

基于选择器的addObserver https://developer.apple.com/documentation/foundation/notificationcenter/1415360-addobserver

如果您使用基于选择器的添加,self(没有令牌)观察者。话虽如此,你应该avoid doing:

NotificationCenter.default.removeObserver(self)

因为您的代码可能不是唯一添加涉及该对象的观察者的代码。删除观察者时,请尽可能提供最具体的细节。例如,如果您使用名称和对象来注册观察者,请使用removeObserver(_:name:object:)与名称和对象。

只有打电话才安全removeObserver(something) in the deinit方法,除此之外不要使用它使用removeObserver(_:name:object:)反而。

Calling removeObserver(self)外面不正确deinit,因为您将删除为该对象设置的所有观察值。在里面调用它deinit并不是不正确,而是毫无意义,因为该对象将立即被释放。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 addObserver 闭包方法在 Swift 5 中删除Observer 的相关文章

  • iOS 13 检查 CLLocationManager 的临时授权状态

    根据 WWDC 视频 https developer apple com videos play wwdc2019 705 https developer apple com videos play wwdc2019 705 当你要求 Al
  • 如何在 iOS 中将 Firebase 对象持久保存到磁盘?

    看起来Firebase http www firebase comiOS 实现不支持客户端模型的离线缓存 这在实践中意味着 对于需要身份验证的 Firebase 应用程序 您需要首先进行身份验证并等待 Firebase 完成登录 检查用户身
  • iPhone SQLite页面缓存不断增长

    I use sqlite数据库用于存储 还有许多数据库事务 我的问题是 sqlite 页面缓存的内存使用量快速增长 在instruments我可以找到这条线 Graph Category Live Bytes Living Transien
  • 如何使用 SwiftUI 获取多个屏幕上的键盘高度并移动按钮

    以下代码获取键盘显示时的键盘高度 并将按钮移动键盘高度 在转换源 ContentView 和转换目标 SecibdContentView 处以相同的方式执行此移动 但按钮在转换目标处不移动 如何使按钮在多个屏幕上移动相同 import Sw
  • 使用 Quartz 创建 PDF 注释 (iOS)

    有人设法使用 Quartz 在现有 PDF 中编写自定义注释吗 我已经使用 CGPDFDocumentRef 等渲染了 PDF 现在工作正常 我成功地阅读了 Annots 字典 if CGPDFDictionaryGetArray page
  • 如何解决 iOS 6 SDK 中的 hidesBottomBarWhenPushed 行为异常的问题?

    我遇到了中描述的相同问题这个 OpenRadar 问题 http www openradar me 14670329 正如那里所说 摘要 UIViewController的hidesBottomBarWhenPushed属性 对于使用 iO
  • Swift:检查 UISearchBar.text 是否包含 url

    如何检查 UISearchBar text 是否包含 URL 我想做这样的事情 if searchBar text NSTextCheckingType Link 但我收到错误 String is not convertible to NS
  • 在情节提要中将 Segue 拖至自身

    我想将一个 Segue 从我的视图控制器拖到其自身 所以我可以推送该特定视图控制器的 无限 实例 我知道如何在代码中执行此操作 即以编程方式实例化视图控制器 但是 我想尽可能使用 segues 我发现了一些在故事板中进行自我延续的 技巧 但
  • NSURLCache 不缓存

    我正在使用 Xcode 6 1 6A1030 iOS7 和 iOS8 模拟器 NSURLCache 似乎没有缓存任何东西 我使用 Cache Control 标头 我的服务器返回带有 max age 6000 的 Cache Control
  • Swift:协议、结构、类

    我开始学习 Swift 语言 但在理解协议 结构和类方面遇到了困难 我来自 Android 方面的编程 所以我相信 Swift 协议基本上是 Java 接口 其中每一个的正确用例是什么 这些类比并不 完全 正确 但这就是我所理解的要点 是的
  • 命令 /Applications/Xcode-beta.app/Contents/Developer/usr/bin/atool 失败,退出代码 255

    它发生在新的 Xcode7 beta 中 CompileAssetCatalog Users admin Library Developer Xcode DerivedData InstaAd ddgdnbxlpxipirebpndfmgr
  • 循环多个 UIAlertController

    在某些情况下 我的应用程序需要显示多个警报消息 错误消息在启动时收集 并且需要一次向用户显示一条 当第一个被确认后 应该呈现下一个 问题在于 显然 它们都试图同时执行 有没有一种聪明的方法可以同步执行此操作 这是一些简单描述我想要做的事情的
  • 带有 allowedEditing 的 UIImagePickerController 不允许平移裁剪

    我在这里看到这个问题 UIImagePicker 允许编辑卡在中心 https stackoverflow com questions 12630155 uiimagepicker allowsediting stuck in center
  • 使用 ZBarSDK 时 iPhone 相机失去自动对焦功能

    我正在开发一个应用程序 用户可以选择是否要扫描条形码或拍摄某物的照片 为了拍照 我正在使用UIImagePickerController照常 为了扫描条形码 我使用 ZbarSDK 1 2ZBarReaderViewController 拍
  • cameraOverlayView 防止使用 allowedEditing 进行编辑

    在我的应用程序中 使用以下行在拍摄照片后对其进行编辑 移动和缩放 效果很好 imagePicker setAllowsEditing YES 但如果我还使用cameraOverlayView 则编辑模式将不再起作用 屏幕出现 但平移和捏合手
  • removeItemAtPath 完成

    我正在以这种方式删除路径上的文件 UIPanGestureRecognizer gesture UIPanGestureRecognizer sender UIButton button UIButton gesture view UIPa
  • XCode 7 中的 AWSS3TransferManagerUploadRequest

    我今天升级到 Xcode 7 Swift 2 0 我的项目正在使用 CocoaPods 我正在 POD 文件中导入所有与 AWS 相关的文件 我已经设置了桥接标头 并导入了 Amazon 告诉我的所有文件 在升级到 Swift 2 0 之前
  • iOS Swift 和 reloadRowsAtIndexPaths 编译错误

    我与 xCode Swift 陷入僵局并刷新 UITableView 的单行 这条线有效 self tableView reloadData 而这条线没有 self tableView reloadRowsAtIndexPaths curr
  • WiFi 网络变化是否有 NSNotificationCenter 通知?

    我想在我的 Cocoa 应用程序中订阅 WiFi 网络更改 但我无法找到合适的事件来订阅 WiFi 网络变化是否有 NSNotificationCenter 通知 据我所知 我会用CoreWLAN https developer apple
  • 如何观察UserDefaults的变化?

    我有一个 ObservedObject在我看来 struct HomeView View ObservedObject var station Station var body some View Text self station sta

随机推荐

  • 单例时间跨多个区域触发 Azure Function

    我有一个时间触发的 Azure 函数部署在多个区域中 我希望在它们之间具有单例行为 例如 如果这些区域是美国西部和欧洲中部 我希望每次只运行其中一个区域 这能实现吗 As the 文档 https learn microsoft com e
  • 安装设备所有者应用程序的更新

    有谁知道更新发生时通过 Google Play 分发的设备所有者应用程序的生产行为是什么 正如我们所知 安装设备所有者应用程序涉及一些动机并且并不容易 重置为出厂默认设置 然后通过 NFC 为设备提供第二个设备等 因此 即使我们认为这一步已
  • g++ 两次链接同一个库会出现问题吗?

    我注意到 当我使用 gcc 制作应用程序并在链接阶段查看输出时 我看到以下库包含两次 home rb01 opt trx HEAD gcc 4 2 4 lib lib64 libstdc so 所以我只是想知道这是 g gcc 的问题还是第
  • 有什么解决方案可以将向量解包为 C++ 中的函数参数吗?

    我实际上正在考虑类似于 python 中的 运算符的东西 如下所示 args 1 2 4 f args C 中有类似的解决方案吗 我能想到的如下 template
  • NetBeans + GWT 2.2.0 + Maven编译问题

    我正在尝试使用 NetBeans 6 9 中的 Google Web Toolkit 创建 Maven Web 应用程序项目 我已按照该视频中显示的步骤进行操作 http www youtube com watch v M iVZ5TJ21
  • 我可以更改点图上的一个标记大小吗?

    使用 Seaborn 的pointplot我创建了以下图像 我想知道是否可以将每个标记的大小更改为唯一值 该图像是通过调用制作的 sns pointplot x Partying y Province ci 95 data df join
  • 发布表单时的 post 与 put

    当评估表单是否已提交时 我检查方法是否为 post 而不是 get 有人告诉我 这是一个好方法 可以了解表单是通过单击 提交 按钮提交的 而不仅仅是由在 url 中传递数据的脚本提交的 put 方法怎么样 看起来和 post 很相似 是否可
  • AngularJS $location 没有模板

    我想使用 locationProviderAngularJS 中的服务 无需在我的中渲染新的 HTML 模板ng view 我有一个div通过按需显示的元素ng show绑定到数据元素的存在 我想通过以下方式将其连接到浏览器位置 locat
  • 使用三元运算符的缺点

    我的源代码中有以下语句 int tableField1 int tableField2 int propertyField1 int propertyField2 if tableField1 null propertyField1 tab
  • 在C中将XImage写入.bmp文件

    我正在使用以下代码将 XImage 写入文件 bitmap0 bmp 但是当我在 fedora 中使用 imageViewer 打开新创建的文件时 它会给出 文件过早结束 错误并且不显示任何内容 谁能指出以下代码中的问题吗 typedef
  • Synthesia 可以很好地播放 MIDI 文件而没有任何音符关闭事件吗?

    我有一个 mid file this https pastebin com amkth128具体一个 除了标题块之外 这里是 MIDI 的相关部分 第一个轨道块仅包含元事件 并被描述为 4D 54 72 6B 00 00 00 52 Tra
  • 从公钥+私钥创建 RSAParamaters 对象

    我需要使用私钥和公钥 key 和 cer 文件 在 Net 中创建 RSAParameters 对象 是否可以在 Net 中做到这一点而不使用第三方软件 如果是这样 我应该去哪里寻找 我最终需要从该对象中提取指数 模数 D P Q DP D
  • XCode 4.3 命令行工具包校验和无效

    Apple 提供的用于使用 Xcode 4 3 安装命令行工具的软件包已损坏 我似乎需要它 因为我正在开发一些命令行工具 有没有人找到 Apple 提供的 Xcode 4 3 的替代命令行包 或者该主题的解决方法 Xcode 包含一个新的
  • 为什么指定的初始化器不能调用其基类中的辅助初始化器?

    根据文档 Objective C 中类的指定初始值设定项必须调用其基类的指定初始值设定项 另一个规则是辅助初始化器必须调用其自己类的指定初始化器 但是 如果遵循第二条规则 为什么指定的初始值设定项不能调用其基类中的辅助初始值设定项 这个基本
  • Flutter 每台设备一个帐户

    如何使一个帐户下的应用程序中只有一个用户 我使用 flutter firebase auth 电子邮件和密码 例如 我有一个帐户 只有我可以从我的设备登录 如果有人发现我的帐户 他将无法登录 谢谢你 我只是给你一个想法如何去做 在cloud
  • SecureRandom 的行为

    尽管在关注了很多文章之后SecureRandom 我在使用时遇到了疑问SecureRandomJava 中的安全 API 在下面的例子中 public class SecureRandomNumber public static void
  • Linux 命令“ll”不起作用[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我可以使用我的用户运行 ll 命令 但不能使用 sudo 它给我错误 因为找不到命令 创建别名ll alias ll ls al
  • Qt 读取访问冲突位于:0x0,flags=0x0(第一次机会)

    我有一段非常简单的代码如下 Letter Vakje geefLetter const return m letter Vakje 类使用 NULL 指针进行初始化m letter 但我仍然收到读取访问冲突错误 有人可以帮忙吗 这是调用该函
  • 如何关闭发生错误后保持打开状态的文件?

    我在用 fid fopen fgfg txt 打开一个文件 有时在我设法关闭文件之前会发生错误 在关闭 Matlab 之前我无法对该文件执行任何操作 如果发生错误 如何关闭文件 首先 你可以使用命令 fclose all 其次 你可以使用试
  • 如何使用 addObserver 闭包方法在 Swift 5 中删除Observer

    这是我的第一篇文章 我是日本 iOS 工程师 这个月刚入职 我有一个麻烦removeObserver的方法NotificationCenter在 Swift 5 中 我通过使用闭包类型将观察者添加到 ViewController VC ad