NSNotification 概念 - 哪段代码放在哪里?
我认为我理解 NSNotification 的概念。它是一个带有基于字符串的通知的集中式广播系统。在一侧张贴,观察另一侧或多侧并采取相应行动。但我的另一部分,即必须编写代码的部分,每次需要通知时都会感到困惑。哪段代码进入哪个标头/实现,哪些文件实际进行观察以及如何防止它变得混乱?是时候理清思路了,你能帮我验证一下这些假设吗?我对第四名相当有信心,但第五名却中了混乱大奖。
- NSNotifications 是在 [NSNotification defaultCenter] 的帮助下创建的,不分配/初始化 NSNotification。正确的?
- 执行 postNofification 功能的对象始终将
self
传递到发布代码中:[[NSNotificationCenter defaultCenter] postNotificationName:@"note name" object:self]
。正确的? - 事件冒泡存在于其他语言中,但不存在于带有 NSNotification 的 Objective-C 中。您不传递通知,而是使通知名称足够具体以供全球广播。正确的?
- 如果您仍然想传递对象 A 发布的通知,您可以在 B 中观察它,处理它并发布一个新的、更具体的通知供对象 C 观察。例如。
@"MenuItemTapped"
从 A 到 B,@"NavigateTo"
从 B 到 C。正确吗? - 通知的名称是 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.
- NSNotifications are created with help from the [NSNotification defaultCenter], one does not alloc/init a NSNotification. Correct?
- The object performing the postNofification feat always passes
self
into the posting code:[[NSNotificationCenter defaultCenter] postNotificationName:@"note name" object:self]
. Correct? - 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?
- 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? - 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 theextern 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?
- One attempt was to create something like a
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你基本上已经明白了。你的数字 1-3 一般是正确的。
extern NSString *const UIKeyboardDidShowNotification
的声明。在一些私有实现文件中是定义。关于上面#4 的特别说明。将通知视为通知,而不是指令。它们通常捕获状态变化或广泛有趣的事件。 “MenuItemTapped”是值得通知的合理事项,但“NavigateTo”通常不是,因为这意味着您正在告诉某个特定对象导航到某个地方。如果是这种情况,该对象可能应该是需要导航的事物的委托(或者应该是属性),并且您应该使其直接发生。当然,这不是必需的,您可以根据需要使用该机制。但是 Cocoa 设计模式通常不使用通知来“告诉对象要做什么”,而只是为了“告诉任何关心将要发生或已经发生的事情的人”。有道理吗?
最后,特别回复一下:#4 中的示例——这些听起来像是真正的 UI 事件,并且看起来整个事情可以通过委托来处理,除非有某种原因导致这些对象需要如此解耦。
You've mostly got it. Your numbers 1-3 are generally correct.
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.
如果您愿意,可以直接创建
NSNotification
对象。postNotificationName:object:
只是一个为您创建、配置和发布通知对象的便捷方法。您可以传递任何您喜欢的对象。其目的是允许通知订阅者仅接收有关特定对象的通知,因此理想情况下,您传入通知所涉及的对象,该对象通常(但并非总是)是
self
。通知不是事件。它们是应用程序内的全局广播。
您不会向特定对象发送通知 - 它们是广播。如果您想向特定对象发送消息,只需调用该对象上的方法即可。
头文件中的外部变量很好。
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.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
.Notifcations are not events. They're global broadcasts within the application.
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.
Externs in the header file are fine.