我需要在满足条件时触发(即随机移动的物体到达某个位置),但是我需要它一直在听,有点像按钮,当你按下时一直在听它。有没有办法做到这一点?
3 回答
您可以使用NotificationCenter
并为其添加观察者:
[[NSNotificationCenter defaultCenter] addObserver:yourObserver selector:yourSelector name:kNotificationName object:nil];
这将使yourObserver
通知发送如下:
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationName object:self userInfo:nil];
您可以阅读参考资料,了解有关发送userInfo
带有通知的对象的更多选项。
编辑:
至于发布通知时,您没有提供太多上下文,但一般来说,知道对象是否已到达给定位置的唯一方法是每次在屏幕上移动对象时检查。
您可能会考虑使用用于游戏的物理引擎之一(花栗鼠、box2d)来检查与固定点的碰撞...但是此选项是否对您有意义取决于您的应用程序...
如果您正在移动响应触摸事件的对象,则检查对象是否已到达指定位置的正确位置是touchesMoved
.
我认为您正在寻找的东西称为键值观察(KVO)。
如果 randomMovingObject 具有包含该点的综合属性,则可以使用以下行开始观察它:
[randomlyMovingObject addObserver:theObserver forKeyPath:@"spot" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
为了对有关现场的变化做出反应,您必须在观察者中实现以下方法:
-(void)observeValueForKeyPath:(NSString *)theKeyPath ofObject:(id)theObject change:(NSDictionary *)change context:(void *)context {
if ([theKeyPath isEqualToString:@"spot"]) {
// react to changes
}
}
每次设置属性时,观察者都会收到通知。
你可能在谈论通知?它们由 表示,并由NSNotification
排队和分派NSNotificationCenter
。
通知中心是系统的共享单例,所以要使用它,你要求它是+defaultCenter
这样的:
NSNotificationCenter *myCenter = [NSNotificationCenter defaultCenter];
您可以通过两种主要方式之一将自己注册为给定通知的观察者。一、传统的:
[myCenter addObserver:self selector:@selector(handleNotification:) name: NSApplicationWillHideNotification object:nil];
这告诉通知中心在发送到队列时发送handleNotification:
选择器self
。NSApplicationWillHideNotification
to 的参数handleNotification:
将是NSNotification
发布到队列的对象。
“名称”决定了您希望收到通知的通知的“类型”或“种类”。我认为在任何地方都没有这些的大规范列表,但大多数都可以通过文档发现。例如,查看“NSApplication Class Reference”,底部有一个名为“Notifications”的完整部分,解释了它发布的内容以及原因。
注意 的最后一个参数-addObserver:selector:name:object:
。如果您在那里传递一个对象而不是nil
,那么您将只会收到从该对象发送的通知(与在系统上任何位置发布的具有该名称的所有通知相反......这可能非常嘈杂。)
请注意,对于您注册的每个通知,您还应该取消注册。如果您的观察者被释放并且通知中心尝试向垃圾内存发送消息,则可能会发生不好的事情!在你的-dealloc
(或同等的)确保你添加:
[myCenter removeObserver:self name:NSApplicationWillHideNotification object:nil];
注册通知的第二种方法是使用块:
[self setMyNotificationObserver:[myCenter addObserverForName:NSApplicationWillHideNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification){
// Do something...
}]];
name:
并且object:
是相同的。但是,不是使用选择器注册对象,而是注册一个块,只要收到具有给定名称的通知,就会调用该块。附加参数“queue”允许您指定在哪个NSOperationQueue
通知上执行。这是使用这种通知处理方式的主要优势之一。通常,在发布原始通知的任何线程上都会调用通知的观察者。这使您可以指定始终在给定线程上调用处理程序。对于必须在主线程上执行的 UI 更新非常有用。
最后,请注意我们将返回的值赋给了-addObserverForName:object:queue:usingBlock:
一个属性myNotificationObserver
。这就是我们在使用块语法时取消注册观察者的方式。我们像这样使用它:
[myCenter removeObserver:[self myNotificationObserver]];
当然,您也可以将自己的自定义通知发布到NSNotificationCenter
. 在通知编程主题中阅读此内容和各种其他通知内容