MVC架构模式传递数据的几种方式(OC)

1.模型M向控制器C传递数据

2.控制器C更新模型M数据

3.视图V从控制器C获取数据

4.控制器C更新视图V数据

5.视图V向控制器C传递数据

6.控制器C调用视图V方法

7.模型M向视图V传递数据

8.视图V向控制器C传递数据(使用代理模式)

======================================================

1.控制器C向视图V传递数据

控制器C可以通过以下方式向视图V传递数据:

@interface UserController : UIViewController
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userView = [[UserView alloc] initWithFrame:self.view.bounds];
    self.userView.nameLabel.text = @"Tom";
    self.userView.ageLabel.text = @"18";
    [self.view addSubview:self.userView];
}
@end

控制器C创建了一个UserView对象,并通过设置其属性来传递数据。视图V可以通过访问属性来获取数据。

2.控制器C从视图V获取数据

控制器C可以通过以下方式从视图V获取数据:

@interface UserController : UIViewController <UITextFieldDelegate>
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userView = [[UserView alloc] initWithFrame:self.view.bounds];
    self.userView.nameTextField.delegate = self;
    self.userView.ageTextField.delegate = self;
    [self.view addSubview:self.userView];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if (textField == self.userView.nameTextField) {
        NSLog(@"name:%@", textField.text);
    } else if (textField == self.userView.ageTextField) {
        NSLog(@"age:%@", textField.text);
    }
}
@end

控制器C实现了UITextFieldDelegate协议中的textFieldDidEndEditing:方法,当文本框结束编辑时,控制器C从文本框中获取数据。

3.控制器C向模型M传递数据

控制器C可以通过以下方式向模型M传递数据:

@interface User : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end

@interface UserController : UIViewController
@property (nonatomic, strong) User *user;
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.user = [[User alloc] init];
    self.userView = [[UserView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.userView];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if (textField == self.userView.nameTextField) {
        self.user.name = textField.text;
    } else if (textField == self.userView.ageTextField) {
        self.user.age = [textField.text integerValue];
    }
}
@end

控制器C实现了UITextFieldDelegate协议中的textFieldDidEndEditing:方法,当文本框结束编辑时,控制器C从文本框中获取数据,并将数据存储在模型M中。

4.模型M向控制器C传递事件

模型M可以通过观察者模式向控制器C传递事件,例如:

@interface User : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end

@interface UserController : UIViewController
@property (nonatomic, strong) User *user;
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.user = [[User alloc] init];
    self.userView = [[UserView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.userView];

    [self.user addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
    [self.user addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)dealloc {
    [self.user removeObserver:self forKeyPath:@"name"];
    [self.user removeObserver:self forKeyPath:@"age"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (object == self.user && [keyPath isEqualToString:@"name"]) {
        NSString *newName = change[NSKeyValueChangeNewKey];
        NSLog(@"name:%@", newName);
    } else if (object == self.user && [keyPath isEqualToString:@"age"]) {
        NSInteger newAge = [change[NSKeyValueChangeNewKey] integerValue];
        NSLog(@"age:%ld", newAge);
    }
}

- (void)buttonTapped {
    self.user.name = @"Tom";
    self.user.age = 18;
}
@end

这个例子中,模型M是User类,控制器C是UserController类,当模型M中的数据发生变化时,模型M会通知控制器C,控制器C可以在observeValueForKeyPath:ofObject:change:context:方法中处理事件。

控制器C可以通过addObserver:forKeyPath:options:context:方法将自己注册为观察者,当指定的keyPath发生变化时,控制器C的observeValueForKeyPath:ofObject:change:context:方法就会被调用。

5.视图V向控制器C传递事件

视图V可以通过委托模式或响应者链向控制器C传递事件,例如:

@interface UserView : UIView
@property (nonatomic, strong) UIButton *button;
@end

@implementation UserView
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
        [self.button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.button];
    }
    return self;
}

- (void)buttonTapped {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"UserViewButtonTapped" object:self];
}
@end

@interface UserController : UIViewController
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userView = [[UserView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.userView];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userViewButtonTapped) name:@"UserViewButtonTapped" object:nil];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)userViewButtonTapped {
    //处理按钮点击事件
}
@end

这个例子中,视图V是UserView类,控制器C是UserController类,当视图V的按钮被点击时,视图V会通过NSNotificationCenter向全局通知中心发送一个名为"UserViewButtonTapped"的通知,控制器C可以通过addObserver:selector:name:object:方法将自己注册为观察者,当指定的通知被发送时,控制器C的userViewButtonTapped方法就会被调用,从而处理按钮点击事件。

6.控制器C向模型M传递数据

控制器C可以通过模型M的setter方法向模型M传递数据,例如:

@interface UserModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end

@implementation UserModel
@end

@interface UserController : UIViewController
@property (nonatomic, strong) UserModel *userModel;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userModel = [[UserModel alloc] init];
    self.userModel.name = @"Tom";
    self.userModel.age = 18;
}

- (void)updateUserModel {
    self.userModel.name = @"Jerry";
    self.userModel.age = 19;
}
@end

控制器C是UserController类,模型M是UserModel类,控制器C可以通过setter方法向模型M传递数据。在viewDidLoad方法中,控制器C创建了一个新的UserModel实例,并设置了name和age属性的初始值。在updateUserModel方法中,控制器C更新了UserModel实例的name和age属性的值。控制器C可以通过调用模型M的getter方法获取数据。

7.模型M向控制器C传递数据

模型M可以通过代理模式向控制器C传递数据,例如:

@protocol UserModelDelegate <NSObject>
- (void)userModelDidUpdateName:(NSString *)name;
- (void)userModelDidUpdateAge:(NSInteger)age;
@end

@interface UserModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, weak) id<UserModelDelegate> delegate;
@end

@implementation UserModel
- (void)setName:(NSString *)name {
    _name = name;
    [self.delegate userModelDidUpdateName:name];
}

- (void)setAge:(NSInteger)age {
    _age = age;
    [self.delegate userModelDidUpdateAge:age];
}
@end

@interface UserController : UIViewController <UserModelDelegate>
@property (nonatomic, strong) UserModel *userModel;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userModel = [[UserModel alloc] init];
    self.userModel.delegate = self;
    self.userModel.name = @"Tom";
    self.userModel.age = 18;
}

- (void)userModelDidUpdateName:(NSString *)name {
    //处理名称更新事件
}

- (void)userModelDidUpdateAge:(NSInteger)age {
    //处理年龄更新事件
}
@end

在这个例子中,控制器C是UserController类,模型M是UserModel类,模型M通过设置代理属性并实现代理协议,向控制器C传递数据。在viewDidLoad方法中,控制器C创建了一个新的UserModel实例,并设置了delegate属性为自身,同时也设置了name和age属性的初始值。在模型M的setter方法中,模型M会通过代理方法向控制器C传递数据。当模型M的name属性或age属性发生变化时,模型M会调用delegate属性的userModelDidUpdateName:或userModelDidUpdateAge:方法,控制器C可以在实现这些代理方法中处理数据更新事件。

8.视图V向控制器C传递数据

视图V可以通过代理模式向控制器C传递数据,例如:

@protocol UserViewDelegate <NSObject>
- (void)userViewDidUpdateName:(NSString *)name;
- (void)userViewDidUpdateAge:(NSInteger)age;
@end

@interface UserView : UIView
@property (nonatomic, weak) id<UserViewDelegate> delegate;
@end

@implementation UserView
- (IBAction)nameTextFieldDidEndEditing:(UITextField *)textField {
    [self.delegate userViewDidUpdateName:textField.text];
}

- (IBAction)ageTextFieldDidEndEditing:(UITextField *)textField {
    [self.delegate userViewDidUpdateAge:[textField.text integerValue]];
}
@end

@interface UserController : UIViewController <UserViewDelegate>
@property (nonatomic, strong) UserView *userView;
@end

@implementation UserController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.userView = [[UserView alloc] init];
    self.userView.delegate = self;
}

- (void)userViewDidUpdateName:(NSString *)name {
    //处理名称更新事件
}

- (void)userViewDidUpdateAge:(NSInteger)age {
    //处理年龄更新事件
}
@end

在这个例子中,控制器C是UserController类,视图V是UserView类,视图V通过设置代理属性并实现代理协议,向控制器C传递数据。在UserView类中,当文本框编辑结束时,视图V会通过代理方法向控制器C传递数据。在UserView的nameTextFieldDidEndEditing:方法和ageTextFieldDidEndEditing:方法中,视图V会调用delegate属性的userViewDidUpdateName:和userViewDidUpdateAge:方法,控制器C可以在实现这些代理方法中处理数据更新事件。在控制器C的viewDidLoad方法中,控制器C创建了一个新的UserView实例,并设置了delegate属性为自身。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容