MST

星途 面试题库

面试题:Objective-C 在iOS视图控制器管理中如何实现视图控制器之间的数据传递

假设你有两个视图控制器ViewControllerA和ViewControllerB,在Objective - C中,通常有哪些方式可以将ViewControllerA中的数据传递到ViewControllerB?请分别阐述每种方式的实现步骤及适用场景。
10.8万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 通过属性传递

  • 实现步骤
    • 在ViewControllerB.h文件中定义接收数据的属性,例如:@property (nonatomic, strong) NSString *dataFromA;
    • 在ViewControllerA中,当准备跳转到ViewControllerB时,创建ViewControllerB的实例,并设置其属性值。如:
ViewControllerB *vcB = [[ViewControllerB alloc] init];
vcB.dataFromA = @"需要传递的数据";
[self.navigationController pushViewController:vcB animated:YES];
  • 适用场景:适用于简单的数据传递,如传递少量的基本数据类型或对象,并且ViewControllerA和ViewControllerB之间存在明确的导航关系(如通过导航控制器进行跳转)。

2. 通过方法传递

  • 实现步骤
    • 在ViewControllerB.h文件中定义接收数据的方法,例如:- (void)setDataFromA:(NSString *)data;
    • 在ViewControllerB.m文件中实现该方法:
- (void)setDataFromA:(NSString *)data {
    _dataFromA = data;
}
  • 在ViewControllerA中,当准备跳转到ViewControllerB时,创建ViewControllerB的实例,并调用其方法传递数据。如:
ViewControllerB *vcB = [[ViewControllerB alloc] init];
[vcB setDataFromA:@"需要传递的数据"];
[self.navigationController pushViewController:vcB animated:YES];
  • 适用场景:同样适用于简单数据传递,当传递数据的逻辑相对复杂,需要在接收方进行一些处理时,通过方法传递数据可以将处理逻辑封装在接收方的方法中,使代码结构更清晰。

3. 通过通知传递

  • 实现步骤
    • 在ViewControllerB中注册通知,通常在viewDidLoad方法中:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveData:) name:@"DataFromAVC" object:nil];
  • 实现接收通知的方法:
- (void)receiveData:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    NSString *data = userInfo[@"data"];
    // 处理数据
}
  • 在ViewControllerA中,当需要传递数据时,发送通知:
NSDictionary *userInfo = @{@"data": @"需要传递的数据"};
[[NSNotificationCenter defaultCenter] postNotificationName:@"DataFromAVC" object:nil userInfo:userInfo];
  • 适用场景:适用于ViewControllerA和ViewControllerB之间没有直接导航关系,或者一个视图控制器需要向多个视图控制器传递数据的情况。但要注意及时移除通知观察者,避免内存泄漏。

4. 通过代理传递

  • 实现步骤
    • 定义代理协议,通常在ViewControllerB.h文件中:
@protocol ViewControllerBDelegate <NSObject>
- (void)passDataToB:(NSString *)data;
@end
  • 在ViewControllerB.h文件中定义代理属性:@property (nonatomic, weak) id<ViewControllerBDelegate> delegate;
  • 在ViewControllerA中,使其遵循代理协议,并实现协议方法:
@interface ViewControllerA () <ViewControllerBDelegate>
@end
@implementation ViewControllerA
- (void)passDataToB:(NSString *)data {
    // 处理传递给B的数据
}
@end
  • 在ViewControllerA中,当创建ViewControllerB实例时,设置其代理为自身:
ViewControllerB *vcB = [[ViewControllerB alloc] init];
vcB.delegate = self;
[self.navigationController pushViewController:vcB animated:YES];
  • 在ViewControllerB中,当需要传递数据时,调用代理方法:
if ([self.delegate respondsToSelector:@selector(passDataToB:)]) {
    [self.delegate passDataToB:@"需要传递的数据"];
}
  • 适用场景:适用于ViewControllerB需要将某些事件或数据反馈给ViewControllerA,并且ViewControllerA和ViewControllerB之间存在一定关联的情况,这种方式使得代码的耦合度相对较低,便于维护和扩展。

5. 通过共享数据模型传递

  • 实现步骤
    • 创建一个共享的数据模型类,例如DataModel.hDataModel.m。在DataModel.h中定义数据属性,如:@property (nonatomic, strong) NSString *sharedData;
    • 在ViewControllerA中,设置共享数据模型中的数据:
DataModel *model = [DataModel sharedInstance];
model.sharedData = @"需要传递的数据";
  • 在ViewControllerB中,获取共享数据模型中的数据:
DataModel *model = [DataModel sharedInstance];
NSString *data = model.sharedData;
  • 适用场景:适用于多个视图控制器之间需要共享数据的场景,方便各个视图控制器对数据进行统一的访问和修改。但要注意数据一致性和多线程访问时的同步问题。