MST

星途 面试题库

面试题:Objective-C在Mac OS开发中多线程与GCD的应用

假设你正在开发一个Mac OS应用,需要从网络下载多个图片并在界面上展示。请使用Objective-C结合Grand Central Dispatch (GCD) 实现该功能,同时要考虑线程安全以及优化下载性能,阐述实现思路并编写关键代码。
27.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建下载队列:使用GCD创建一个并发队列来处理图片下载任务,这样可以同时下载多个图片,提高下载性能。
  2. 线程安全:在更新UI(展示图片)时,必须在主线程进行,因为UIKit不是线程安全的。使用dispatch_async(dispatch_get_main_queue(), ^{...})将更新UI的代码块提交到主线程执行。
  3. 优化下载性能:可以设置合理的并发数,避免过多的并发请求导致网络资源耗尽。另外,可以使用NSURLSession的默认配置来复用网络连接,提高效率。

关键代码

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface ViewController : UIViewController

@property (nonatomic, strong) NSMutableDictionary<NSURL *, UIImage *> *imageCache;
@property (nonatomic, strong) dispatch_queue_t downloadQueue;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageCache = [NSMutableDictionary dictionary];
    self.downloadQueue = dispatch_queue_create("com.example.imageDownloadQueue", DISPATCH_QUEUE_CONCURRENT);
    
    NSArray<NSURL *> *imageURLs = @[
        [NSURL URLWithString:@"http://example.com/image1.jpg"],
        [NSURL URLWithString:@"http://example.com/image2.jpg"],
        [NSURL URLWithString:@"http://example.com/image3.jpg"]
    ];
    
    for (NSURL *url in imageURLs) {
        [self downloadImageWithURL:url];
    }
}

- (void)downloadImageWithURL:(NSURL *)url {
    dispatch_async(self.downloadQueue, ^{
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        if (imageData) {
            UIImage *image = [UIImage imageWithData:imageData];
            if (image) {
                [self.imageCache setObject:image forKey:url];
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    // 这里假设你有一个UIImageView来展示图片,根据实际情况修改
                    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
                    imageView.image = image;
                    [self.view addSubview:imageView];
                });
            }
        }
    });
}

@end