NSNotification 概念 - 哪段代码放在哪里?

发布于 2024-10-13 05:54:37 字数 1225 浏览 7 评论 0原文

我认为我理解 NSNotification 的概念。它是一个带有基于字符串的通知的集中式广播系统。在一侧张贴,观察另一侧或多侧并采取相应行动。但我的另一部分,即必须编写代码的部分,每次需要通知时都会感到困惑。哪段代码进入哪个标头/实现,哪些文件实际进行观察以及如何防止它变得混乱?是时候理清思路了,你能帮我验证一下这些假设吗?我对第四名相当有信心,但第五名却中了混乱大奖。


  1. NSNotifications 是在 [NSNotification defaultCenter] 的帮助下创建的,不分配/初始化 NSNotification。正确的?
  2. 执行 postNofification 功能的对象始终将 self 传递到发布代码中:[[NSNotificationCenter defaultCenter] postNotificationName:@"note name" object:self]。正确的?
  3. 事件冒泡存在于其他语言中,但不存在于带有 NSNotification 的 Objective-C 中。您不传递通知,而是使通知名称足够具体以供全球广播。正确的?
  4. 如果您仍然想传递对象 A 发布的通知,您可以在 B 中观察它,处理它并发布一个新的、更具体的通知供对象 C 观察。例如。 @"MenuItemTapped" 从 A 到 B,@"NavigateTo" 从 B 到 C。正确吗?
  5. 通知的名称是 NSString。因为发布者和观察者都希望避免拼写错误,所以我们将 NSString 常量存储在 [extern const|define|class method|none of the above] 中。你能帮我选一个吗?
    • 一种尝试是创建类似 NotificationNames.h 文件,其中包含所有 extern NSString *const NOTE_NAME 声明。但这会破坏通知的可移植性。
    • 另一个尝试是对 NSNotification 进行子类化(使用 XCode 模板来保持创建速度快),但因为这个概念是从 AS3 中的 Event 类子类化而来的,所以看起来非常不客观。还有一个奇怪的地方是你不能在 NSNotification 上调用 [super init],所以事情开始失控。
    • 我在这方面的麻烦源于繁琐的 #import 语句。如何最大限度地减少拼写错误,同时保持常量/定义的可移植性?

Part of me thinks I understand the NSNotification concept. It's a centralized broadcast system with string based notifications. Post on one side, observe on one or multiple other sides and act accordingly. Another part of me though, the part that has to write the code, gets confused every time I need a notification. What piece of code goes into which header/implementation, what files actually do the observing and how do I keep it from becoming a mess? Time to straighten it out, will you help me verify these assumptions? I'm fairly confident up to number 4, but number 5 hits the confusion jackpot.


  1. NSNotifications are created with help from the [NSNotification defaultCenter], one does not alloc/init a NSNotification. Correct?
  2. The object performing the postNofification feat always passes self into the posting code: [[NSNotificationCenter defaultCenter] postNotificationName:@"note name" object:self]. Correct?
  3. Event bubbling exists in other languages, but not in Objective-C with NSNotification. You don't pass along notifications, you make the notification name specific enough for the global broadcast. Correct?
  4. If you still want to pass along a notification posted by object A, you observe it in B, handle it and post a new, more specific notification for object C to observe. Eg. @"MenuItemTapped" from A to B, and @"NavigateTo" from B to C. Correct?
  5. The name of a notification is a NSString. Because both the poster and the observer want to avoid typos, we store the NSString constant in a [extern const|define|class method|none of the above]. Could you help me pick one?
    • One attempt was to create something like a NotificationNames.h file, which would contain all the extern NSString *const NOTE_NAME declarations. Yet that undermines the portability of a notification.
    • Another attempt was to subclass NSNotification (with an XCode template to keep the creation fast), but because this concept is taken from subclassing the Event-class in AS3, it seemed very un-objective-c-ish. There's also the weirdness that you can't call [super init] on a NSNotification, so things started to get out of hand.
    • My troubles with this one arise from the cumbersome #import statements. How to minimize typo's, yet keep the constants/defines portable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忘你却要生生世世 2024-10-20 05:54:37

你基本上已经明白了。你的数字 1-3 一般是正确的。

  • 您不需要分配自己的 NSNotification 对象。
  • 正如您所说,您通常将“自我”作为通知的“对象”传递,但如果您在概念上“代表”其他事物进行通知,则也可以传递其他内容。但这种情况不太常见。
  • 通知与 UI 中的“事件”不同。 Cocoa 确实有事件;它们是鼠标/键盘/触摸事件,并且它们通过 UI 对象“冒泡”到“响应者链”上。通知是一种完全独立的机制,不依赖于 UI,它通常用于在其他解耦/独立对象之间进行全局广播。它更类似于一个对象有多个委托。
  • 是的,您应该在每个使用它的人都可以看到的地方定义通知的名称。在 Cocoa 本身中,这通常是一个公共标头,带有类似 extern NSString *const UIKeyboardDidShowNotification 的声明。在一些私有实现文件中是定义。

关于上面#4 的特别说明。将通知视为通知,而不是指令。它们通常捕获状态变化或广泛有趣的事件。 “MenuItemTapped”是值得通知的合理事项,但“NavigateTo”通常不是,因为这意味着您正在告诉某个特定对象导航到某个地方。如果是这种情况,该对象可能应该是需要导航的事物的委托(或者应该是属性),并且您应该使其直接发生。当然,这不是必需的,您可以根据需要使用该机制。但是 Cocoa 设计模式通常不使用通知来“告诉对象要做什么”,而只是为了“告诉任何关心将要发生或已经发生的事情的人”。有道理吗?

最后,特别回复一下:#4 中的示例——这些听起来像是真正的 UI 事件,并且看起来整个事情可以通过委托来处理,除非有某种原因导致这些对象需要如此解耦。

You've mostly got it. Your numbers 1-3 are generally correct.

  • You shouldn't ever need to alloc your own NSNotification object.
  • You generally pass "self" as the "object" of the notification as you say, but you could also pass something else in if you are notifying "on behalf of" something else, conceptually. But that would be less common case.
  • Notifications aren't the same as "events" in the UI. Cocoa does have events; they are mouse/keyboard/touch events, and they do "bubble" up the "responder chain" through the UI objects. Notifications are a totally independent mechanism that is not tied to UI, and it is used for generally global broadcast among otherwise decoupled/independent objects. It's more akin to having multiple delegates for an object.
  • Yes, you should define the name of the notification somewhere that everyone who uses it can see. In Cocoa itself, this is usually a public header with a declaration like extern NSString *const UIKeyboardDidShowNotification. In some private implementation file is the definition.

A special note regarding your #4 above. Think of notifications as notifications, not as instructions. They usually capture state changes or broadly interesting events. "MenuItemTapped" is a reasonable thing to notify about, but "NavigateTo" usually isn't, because the implication is that you're telling some specific object to navigate somewhere. If that's the case, that object should probably be a delegate (or should be a property) of the thing that wants the navigation, and you should cause it to happen directly. This isn't a requirement, of course, and you can use the mechanism for whatever you want. But the Cocoa design patterns generally don't use notifications for "telling objects what to do", only for "telling whoever cares what will/did happen". Make sense?

Finally, specifically re: your examples in #4-- those sound like genuine UI events, and seem like the whole thing could be handled via delegation, unless there's some reason why those objects need to be so decoupled.

一向肩并 2024-10-20 05:54:37
  1. 如果您愿意,可以直接创建 NSNotification 对象。 postNotificationName:object: 只是一个为您创建、配置和发布通知对象的便捷方法。

  2. 您可以传递任何您喜欢的对象。其目的是允许通知订阅者仅接收有关特定对象的通知,因此理想情况下,您传入通知所涉及的对象,该对象通常(但并非总是)是 self

  3. 通知不是事件。它们是应用程序内的全局广播。

  4. 您不会向特定对象发送通知 - 它们是广播。如果您想向特定对象发送消息,只需调用该对象上的方法即可。

  5. 头文件中的外部变量很好。

  1. You can directly create NSNotification objects if you so wish. postNotificationName:object: is just a convenience method that creates, configures and posts a notification object for you.

  2. You can pass any object you like. Its purpose is to allow notification subscribers to only receive notifications about a particular object, so ideally you pass in the object the notification is about, which will often - but not always - be self.

  3. Notifcations are not events. They're global broadcasts within the application.

  4. You don't send notifications to a particular object - They're broadcasts. If you want to send a message to a particular object, you just call a method on that object.

  5. Externs in the header file are fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文