MST

星途 面试题库

面试题:Objective-C中Block在复杂场景下的回调应用

假设你正在开发一个网络请求模块,需要使用Block进行回调处理响应数据。要求实现一个带有缓存机制的网络请求方法,当缓存中有数据时直接返回缓存数据并通过Block回调,否则发起网络请求,请求成功后更新缓存并通过Block回调数据。请详细阐述设计思路并给出核心代码实现。
46.9万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 缓存设计:使用一个字典(如NSMutableDictionary)来存储缓存数据,以请求的URL作为键,响应数据作为值。
  2. 网络请求:利用常见的网络请求框架(如AFNetworking或URLSession)来发起网络请求。
  3. 回调处理:通过Block来传递响应数据,无论是从缓存获取还是网络请求成功后。

核心代码实现(以Objective - C为例,使用AFNetworking)

#import <AFNetworking/AFNetworking.h>

@interface NetworkRequestManager : NSObject

@property (nonatomic, strong) NSMutableDictionary *cacheDictionary;

+ (instancetype)sharedManager;
- (void)requestWithURL:(NSURL *)url completion:(void(^)(id responseObject, NSError *error))completion;

@end

@implementation NetworkRequestManager

+ (instancetype)sharedManager {
    static NetworkRequestManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[NetworkRequestManager alloc] init];
        manager.cacheDictionary = [NSMutableDictionary dictionary];
    });
    return manager;
}

- (void)requestWithURL:(NSURL *)url completion:(void(^)(id responseObject, NSError *error))completion {
    // 检查缓存
    id cachedResponse = self.cacheDictionary[url.absoluteString];
    if (cachedResponse) {
        completion(cachedResponse, nil);
        return;
    }
    
    // 发起网络请求
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager GET:url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 更新缓存
        self.cacheDictionary[url.absoluteString] = responseObject;
        completion(responseObject, nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        completion(nil, error);
    }];
}

@end

使用示例

NSURL *url = [NSURL URLWithString:@"https://example.com/api"];
[[NetworkRequestManager sharedManager] requestWithURL:url completion:^(id responseObject, NSError *error) {
    if (!error) {
        NSLog(@"Response: %@", responseObject);
    } else {
        NSLog(@"Error: %@", error);
    }
}];

核心代码实现(以Swift为例,使用URLSession)

class NetworkRequestManager {
    static let shared = NetworkRequestManager()
    private var cacheDictionary = [String: Any]()
    
    func request(with url: URL, completion: @escaping (Any?, Error?) -> Void) {
        if let cachedResponse = cacheDictionary[url.absoluteString] {
            completion(cachedResponse, nil)
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else {
                completion(nil, error)
                return
            }
            do {
                let responseObject = try JSONSerialization.jsonObject(with: data, options: [])
                self.cacheDictionary[url.absoluteString] = responseObject
                completion(responseObject, nil)
            } catch {
                completion(nil, error)
            }
        }
        task.resume()
    }
}

使用示例

let url = URL(string: "https://example.com/api")!
NetworkRequestManager.shared.request(with: url) { responseObject, error in
    if let error = error {
        print("Error: \(error)")
    } else if let responseObject = responseObject {
        print("Response: \(responseObject)")
    }
}