MST
星途 面试题库

面试题:Objective-C协议对象化语法的应用场景

说明Objective-C协议对象化语法(例如`@protocol MyProtocol <NSObject>;`然后`Protocol *myProto = @protocol(MyProtocol);`)的常见应用场景。在实际项目中,这种对象化协议的方式如何帮助你实现更灵活的代码设计,举一个具体的例子并详细说明。
48.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

常见应用场景

  1. 依赖注入:在设计对象之间的依赖关系时,使用对象化协议可以方便地将不同实现类通过协议类型进行注入,提高代码的可测试性和可维护性。例如,一个视图控制器需要一个数据加载器,通过协议定义数据加载的方法,然后可以在运行时根据不同情况注入不同的数据加载实现类。
  2. 多态实现:可以根据不同的业务场景,让多个类遵循同一个协议,通过对象化协议来统一处理这些遵循协议的类实例,实现多态效果。
  3. 框架扩展:在开发框架时,使用对象化协议可以提供一种灵活的扩展机制,外部开发者可以通过遵循框架定义的协议来扩展框架功能。

具体例子

假设我们正在开发一个电商应用,其中有一个商品展示模块。商品数据可能从不同的数据源获取,比如本地数据库、网络接口等。

  1. 定义协议
@protocol ProductDataSource <NSObject>
- (NSArray *)fetchProducts;
@end
  1. 对象化协议
Protocol *productDataSourceProto = @protocol(ProductDataSource);
  1. 不同数据源实现类
  • 本地数据源
@interface LocalProductDataSource : NSObject <ProductDataSource>
- (NSArray *)fetchProducts {
    // 从本地数据库获取商品数据逻辑
    return @[];
}
@end
  • 网络数据源
@interface NetworkProductDataSource : NSObject <ProductDataSource>
- (NSArray *)fetchProducts {
    // 从网络获取商品数据逻辑
    return @[];
}
@end
  1. 商品展示视图控制器
@interface ProductViewController : UIViewController {
    id<ProductDataSource> dataSource;
}
- (instancetype)initWithDataSource:(id<ProductDataSource>)source {
    if (self = [super init]) {
        dataSource = source;
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *products = [dataSource fetchProducts];
    // 展示商品逻辑
}
@end
  1. 使用场景 在应用启动时,可以根据网络状态或者用户设置来决定使用哪种数据源。
if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable) {
    NetworkProductDataSource *networkSource = [[NetworkProductDataSource alloc] init];
    ProductViewController *vc = [[ProductViewController alloc] initWithDataSource:networkSource];
} else {
    LocalProductDataSource *localSource = [[LocalProductDataSource alloc] init];
    ProductViewController *vc = [[ProductViewController alloc] initWithDataSource:localSource];
}

通过这种对象化协议的方式,我们实现了商品展示模块与数据源的解耦,使得代码在数据源变更时更加灵活,不需要对商品展示视图控制器的核心代码进行大量修改,同时也方便进行单元测试,例如可以通过模拟数据源对象来测试视图控制器的功能。