Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 是否可以将数据作为通知的一部分传递?_Objective C_Ios_Model View Controller - Fatal编程技术网

Objective c 是否可以将数据作为通知的一部分传递?

Objective c 是否可以将数据作为通知的一部分传递?,objective-c,ios,model-view-controller,Objective C,Ios,Model View Controller,场景,在纸牌游戏中: 用户在屏幕上移动卡片。由于移动,卡的坐标发生变化。如果发现卡位于某个特定位置,我们希望确保更新卡对象(模型)以包含这些坐标 但是视图不应该直接与模型对话,所以 取而代之的是直接更新卡片,视图将通知其控制器“卡片已着陆”。收到此通知后,我希望控制器更新卡的位置,而不是视图(控制器更新模型) 问题1: 我是否正确地考虑了这种情况 问题2: 是否可以将数据与通知一起发送到控制器?这就是NSNotification的userInfo字典和object的作用。在本例中,它是您想要的对

场景,在纸牌游戏中:

用户在屏幕上移动卡片。由于移动,卡的坐标发生变化。如果发现卡位于某个特定位置,我们希望确保更新卡对象(模型)以包含这些坐标

但是视图不应该直接与模型对话,所以

取而代之的是直接更新卡片,视图将通知其控制器“卡片已着陆”。收到此通知后,我希望控制器更新卡的位置,而不是视图(控制器更新模型)

问题1: 我是否正确地考虑了这种情况

问题2:
是否可以将数据与通知一起发送到控制器?

这就是
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的见解。刚从你的评论中得到一个想法。谢谢你