app有很多界面,如果A界面修改了数据某个值,如何保证B界面的数据也能被修改
通常想法如下:
- 给A控制器增加一个成员变量指向B
- 创建B界面的时候就赋值给这个变量
- 当A修改了数据以后,调用成员变量的方法更新B界面的数据
搭建界面如下
在A界面HYWAddController.h文件中增加变量指向B
1
2
3
| @class HYWContact,HYWContactController;
/**拥有联系人控制器,以便传递模型 */
@property (nonatomic, strong) HYWContactController *contactVc;
|
在B界面HYWContactController.h文件中,增加模型属性,重写set方法,接收A传过来得数据
1
2
| /**模型 */
@property (nonatomic, strong) HYWContact *contact;
|
在B界面HYWContactController.m文件中,创建B界面push的时候,将A赋值给B界面的变量,并且重写set方法
1
2
3
4
5
6
7
8
9
10
11
12
13
| - (void)add
{
HYWAddController *addVc = [[HYWAddController alloc] init];
addVc.title = @"添加通讯录";
addVc.contactVc = self;
[self.navigationController pushViewController:addVc animated:YES];
}
- (void)setContact:(HYWContact *)contact
{
_contact = contact;
[self.contacts addObject:contact];
[self.tableView reloadData];
}
|
A界面跳转的时候,修改模型,并通过成员变量调取B界面,并且调用set方法,进行赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
| - (IBAction)addContact:(id)sender {
// 修改数据
HYWContact *contact = [[HYWContact alloc] init];
contact.name = self.nameTextField.text;
contact.phone = self.phoneTextField.text;
contact.icon = @"180008225874";
// 调取B界面,调用set方法更新数据
self.contactVc.contact = contact;
从A界面跳到B界面
[self.navigationController popViewControllerAnimated:YES];
}
|
这种想法比较简单,但是实现复杂,而且A界面和B界面耦合性太强,利用代理传递数据进行解耦
- A界面增加代理属性,代理方法
- 当数据更新后,通知代理更新了数据
- 任何一个对象只要成为A的代理,就可以获得A传过来的数据
在A界面HYWAddController.h中增加代理属性和代理方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #import <UIKit/UIKit.h>
@class HYWAddController,HYWContact;
@protocol HYWAddControllerDelegate <NSObject>
@optional
- (void)addControllerDidClickAddButton:(HYWAddController *)addVc withContact:(HYWContact *)contact;
@end
@interface HYWAddController : UIViewController
/**代理 */
@property (nonatomic, weak) id <HYWAddControllerDelegate> delegate;
@end
|
当A跳转的时候,更新数据,并通知代理,数据作为参数传递出去
1
2
3
4
5
6
7
8
9
10
11
| - (IBAction)addContact:(id)sender {
HYWContact *contact = [[HYWContact alloc] init];
contact.name = self.nameTextField.text;
contact.phone = self.phoneTextField.text;
contact.icon = @"180008225874";
if ([self.delegate respondsToSelector:@selector(addControllerDidClickAddButton:withContact:)]) {
[self.delegate addControllerDidClickAddButton:self withContact:contact];
}
[self.navigationController popViewControllerAnimated:YES];
}
|
在B界面HYWContactController.m文件中,设置为A的代理,并实现A的代理方法,后去传过来的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@interface HYWContactController () <HYWAddControllerDelegate>
- (void)add
{
HYWAddController *addVc = [[HYWAddController alloc] init];
addVc.delegate = self;
addVc.title = @"添加通讯录";
[self.navigationController pushViewController:addVc animated:YES];
}
#pragma mark - HYWAddControllerDelegate 代理方法
- (void)addControllerDidClickAddButton:(HYWAddController *)addVc withContact:(HYWContact *)contact
{
[self.contacts addObject:contact];
[self.tableView reloadData];
}
|
代理方法更简单,A传递数据,B成为代理就可以接受,不成为代理就与A没有关系,就算成为A的代理,不实现代理方法还是与A没有关系.成功地接触了A和B的耦合性