MST

星途 面试题库

面试题:Objective-C中观察者模式在复杂业务场景的应用

假设你正在开发一个iOS应用,其中有一个新闻订阅功能,用户可以订阅不同类型的新闻(如体育、科技、娱乐等)。当有新的对应类型新闻发布时,要及时通知订阅该类型新闻的用户。请使用Objective-C的观察者模式来设计并阐述实现思路,包括如何管理不同类型新闻的观察者列表以及如何高效地通知相关观察者。
23.0万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 定义新闻类型枚举

    typedef NS_ENUM(NSUInteger, NewsType) {
        NewsTypeSports,
        NewsTypeTech,
        NewsTypeEntertainment
    };
    
  2. 定义观察者协议

    @protocol NewsObserver <NSObject>
    - (void)newNewsAvailable:(NSString *)newsContent forType:(NewsType)type;
    @end
    
  3. 管理观察者列表

    • 创建一个NewsPublisher类来管理观察者列表。
    • 使用NSMutableDictionary来存储不同类型新闻的观察者列表,键为NewsType,值为NSMutableArray,数组中存放实现了NewsObserver协议的对象。
    @interface NewsPublisher : NSObject
    - (void)addObserver:(id<NewsObserver>)observer forType:(NewsType)type;
    - (void)removeObserver:(id<NewsObserver>)observer forType:(NewsType)type;
    - (void)publishNews:(NSString *)newsContent forType:(NewsType)type;
    @end
    
    @implementation NewsPublisher {
        NSMutableDictionary<NSNumber *, NSMutableArray<id<NewsObserver>> *> *observerLists;
    }
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            observerLists = [NSMutableDictionary dictionary];
            for (NSUInteger i = 0; i < 3; i++) {
                NSNumber *typeNumber = @(i);
                observerLists[typeNumber] = [NSMutableArray array];
            }
        }
        return self;
    }
    
    - (void)addObserver:(id<NewsObserver>)observer forType:(NewsType)type {
        NSNumber *typeNumber = @(type);
        [observerLists[typeNumber] addObject:observer];
    }
    
    - (void)removeObserver:(id<NewsObserver>)observer forType:(NewsType)type {
        NSNumber *typeNumber = @(type);
        [observerLists[typeNumber] removeObject:observer];
    }
    
    - (void)publishNews:(NSString *)newsContent forType:(NewsType)type {
        NSNumber *typeNumber = @(type);
        NSArray<id<NewsObserver>> *observers = observerLists[typeNumber];
        for (id<NewsObserver> observer in observers) {
            [observer newNewsAvailable:newsContent forType:type];
        }
    }
    @end
    
  4. 实现思路阐述

    • 添加观察者addObserver:forType:方法将观察者添加到对应类型新闻的观察者列表中。
    • 移除观察者removeObserver:forType:方法从对应类型新闻的观察者列表中移除观察者。
    • 发布新闻并通知观察者publishNews:forType:方法获取对应类型新闻的观察者列表,然后遍历列表,调用每个观察者的newNewsAvailable:forType:方法,高效地通知所有订阅该类型新闻的观察者。
  5. 使用示例

    // 创建新闻发布者
    NewsPublisher *publisher = [[NewsPublisher alloc] init];
    
    // 创建一个观察者类并实现协议方法
    @interface MyObserver : NSObject <NewsObserver>
    @end
    
    @implementation MyObserver
    - (void)newNewsAvailable:(NSString *)newsContent forType:(NewsType)type {
        NSString *typeStr = nil;
        switch (type) {
            case NewsTypeSports:
                typeStr = @"体育";
                break;
            case NewsTypeTech:
                typeStr = @"科技";
                break;
            case NewsTypeEntertainment:
                typeStr = @"娱乐";
                break;
        }
        NSLog(@"收到 %@ 新闻: %@", typeStr, newsContent);
    }
    @end
    
    MyObserver *observer = [[MyObserver alloc] init];
    // 订阅体育新闻
    [publisher addObserver:observer forType:NewsTypeSports];
    
    // 发布体育新闻
    [publisher publishNews:@"湖人队赢得比赛" forType:NewsTypeSports];
    
    // 移除观察者
    [publisher removeObserver:observer forType:NewsTypeSports];