Objective c 是否可以将数据作为通知的一部分传递?
场景,在纸牌游戏中: 用户在屏幕上移动卡片。由于移动,卡的坐标发生变化。如果发现卡位于某个特定位置,我们希望确保更新卡对象(模型)以包含这些坐标 但是视图不应该直接与模型对话,所以 取而代之的是直接更新卡片,视图将通知其控制器“卡片已着陆”。收到此通知后,我希望控制器更新卡的位置,而不是视图(控制器更新模型) 问题1: 我是否正确地考虑了这种情况 问题2:Objective c 是否可以将数据作为通知的一部分传递?,objective-c,ios,model-view-controller,Objective C,Ios,Model View Controller,场景,在纸牌游戏中: 用户在屏幕上移动卡片。由于移动,卡的坐标发生变化。如果发现卡位于某个特定位置,我们希望确保更新卡对象(模型)以包含这些坐标 但是视图不应该直接与模型对话,所以 取而代之的是直接更新卡片,视图将通知其控制器“卡片已着陆”。收到此通知后,我希望控制器更新卡的位置,而不是视图(控制器更新模型) 问题1: 我是否正确地考虑了这种情况 问题2: 是否可以将数据与通知一起发送到控制器?这就是NSNotification的userInfo字典和object的作用。在本例中,它是您想要的对
是否可以将数据与通知一起发送到控制器?这就是
NSNotification
的userInfo
字典和object
的作用。在本例中,它是您想要的对象。例如:
// In your model header file
extern NSString * const CardMovedNotification;
// In your model implementation file
NSString * const CardMovedNotification = @"CardMoved";
...
[[NSNotificationCenter defaultCenter] postNotificationName:CardMovedNotification object:theCardThatMoved];
然后,您的观察者可以通过[notification object]
获得该卡。如果需要传递更多信息,您可以创建一个字典,并通过postNotificationName:object:userInfo:
以userInfo
的形式传递。然后,观察者可以通过[notification userInfo]
查询它,这就是NSNotification
的userInfo
字典和对象的用途。在本例中,它是您想要的对象。例如:
// In your model header file
extern NSString * const CardMovedNotification;
// In your model implementation file
NSString * const CardMovedNotification = @"CardMoved";
...
[[NSNotificationCenter defaultCenter] postNotificationName:CardMovedNotification object:theCardThatMoved];
然后,您的观察者可以通过[notification object]
获得该卡。如果需要传递更多信息,您可以创建一个字典,并通过postNotificationName:object:userInfo:
以userInfo
的形式传递。然后,观察者可以通过[notification userInfo]
查询,您的场景不需要NSNotifications
:一种简单的基于代理的方法就可以了
视图应该定义一个委托接口,并提供一个非保留的委托
属性。控制器应该实现委托接口,并将自身设置为视图的委托。然后,视图将通知其委托,甚至不知道它通知了控制器。然后,控制器将通知传递给模型
@protocol CardDelegate
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos;
@end
@interface MyView
@property (weak, nonatomic,readwrite) id<CardDelegate> delegate;
@end
@implementation MyViewController
-(id)init { // This should be in your designated initializer
self = [super init];
if (self) {
MyView *view = [[MyView alloc] init];
view.delegate = self;
self.view = view;
}
return self;
}
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos {
// Update the model
}
@end
@implementation MyView
@synthesize delegate;
-(void) doSomething {
// ...
if (cardHasLanded) {
[delegate cardHasLanded:card atPosition:pos];
}
// ... more code
}
@end
@协议卡代理
-(无效)卡已登陆:(SOCard*)卡在位置:(SOPosition*)位置;
@结束
@接口MyView
@属性(弱、非原子、读写)id委托;
@结束
@MyViewController的实现
-(id)init{//这应该在指定的初始值设定项中
self=[super init];
如果(自我){
MyView*view=[[MyView alloc]init];
view.delegate=self;
self.view=视图;
}
回归自我;
}
-(无效)卡已着陆:(SOCard*)卡在位置:(SOPosition*)位置{
//更新模型
}
@结束
@实现MyView
@综合代表;
-(无效)剂量{
// ...
如果(卡已着陆){
[代表卡已登陆:卡在位置:pos];
}
//…更多代码
}
@结束
对于您的场景,您不需要NSNotifications
:一种简单的基于委托的方法就可以了
视图应该定义一个委托接口,并提供一个非保留的委托
属性。控制器应该实现委托接口,并将自身设置为视图的委托。然后,视图将通知其委托,甚至不知道它通知了控制器。然后,控制器将通知传递给模型
@protocol CardDelegate
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos;
@end
@interface MyView
@property (weak, nonatomic,readwrite) id<CardDelegate> delegate;
@end
@implementation MyViewController
-(id)init { // This should be in your designated initializer
self = [super init];
if (self) {
MyView *view = [[MyView alloc] init];
view.delegate = self;
self.view = view;
}
return self;
}
-(void)cardHasLanded:(SOCard*)card atPosition:(SOPosition*)pos {
// Update the model
}
@end
@implementation MyView
@synthesize delegate;
-(void) doSomething {
// ...
if (cardHasLanded) {
[delegate cardHasLanded:card atPosition:pos];
}
// ... more code
}
@end
@协议卡代理
-(无效)卡已登陆:(SOCard*)卡在位置:(SOPosition*)位置;
@结束
@接口MyView
@属性(弱、非原子、读写)id委托;
@结束
@MyViewController的实现
-(id)init{//这应该在指定的初始值设定项中
self=[super init];
如果(自我){
MyView*view=[[MyView alloc]init];
view.delegate=self;
self.view=视图;
}
回归自我;
}
-(无效)卡已着陆:(SOCard*)卡在位置:(SOPosition*)位置{
//更新模型
}
@结束
@实现MyView
@综合代表;
-(无效)剂量{
// ...
如果(卡已着陆){
[代表卡已登陆:卡在位置:pos];
}
//…更多代码
}
@结束
我同意不需要通知。通常对于UI对象坐标,我不会使用模型对象,因为坐标耦合到UI对象(或者在哪里绘制?)。您需要做的是将控制器注册到触摸结束事件,该事件传入进行触摸的UI对象,并更新(在响应控制器方法中)对象的坐标(如果它们确实在所需位置内)。(与按钮和其他UI对象一样)我同意不需要通知。通常对于UI对象坐标,我不会使用模型对象,因为坐标耦合到UI对象(或者在哪里绘制?)。您需要做的是将控制器注册到触摸结束事件,该事件传入进行触摸的UI对象,并更新(在响应控制器方法中)对象的坐标(如果它们确实在所需位置内)。(与按钮和其他UI对象一样)响应良好。谢谢在您的示例中,控制器是否需要实现协议?看起来不像,但我想确定的是,虽然委托方法也是一种标准的设计模式,在这里肯定非常有用,但通知方法的优点是,新的观察者很容易对动作做出响应。例如,想要进行一些统计的对象也可以观察通知,而不需要在发送方进行任何更改。有了委托模式,就不那么容易了,而且可能会产生更紧密的耦合。我们需要将其改为侦听器模式,以保持松散耦合。感谢您对DarkDust的见解。刚从你的评论中得到一个想法。谢谢你