1

我正在用 Objective C 和 Cocoa for Mac OS X 编写一个应用程序,它从外部源加载 GIF 并将它们显示在屏幕上。用户搜索一个词,GIF 被下载并放置到 NSImageViews 中,然后这些视图显示在滚动视图中。

早些时候,GIF 按预期进行了动画处理。然后我尝试使用 NSThread 来加载 GIF 并将其添加到与主线程分开的滚动视图中。这是线程中调用的方法:

    - (void)threading:(id)obj
{

    NSURL *url = [NSURL URLWithString: @"URL HERE"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setURL:url];
    [request setHTTPMethod:@"GET"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

    NSError *error;
    NSURLResponse *response;
    NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];


    NSArray *gifs = [data objectForKey:@"data"];        


    for (int i = 0; i < 1; i++) { // try to load 1 gif
        NSString *currentGifURL = @"whatever";
        NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
        // I tried using these 2 lines, still didn't work
        //[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
        NSURL *imageURL = [NSURL URLWithString:currentGifURL];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        NSImage *image = [[NSImage alloc] initWithData:imageData];
        imgView.image = image;
        [_scrollView.documentView addSubview:imgView];

    }        
    [_progressIndicator stopAnimation:self];
}

我后来打电话

[NSThread detachNewThreadSelector:@selector(threading:) toTarget:self withObject:nil];

创建线程。图像出现在屏幕上,但只显示第一帧——它们不是动画的。从字面上用线程内部的代码替换线程初始化会呈现相同的视图,除了 GIF 是动画的。线程中有什么东西会阻止 GIF 动画吗?

谢谢!

4

1 回答 1

1

NSImageView不是线程安全的。利用- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

- (void)threading:(id)obj
{

NSURL *url = [NSURL URLWithString: @"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setURL:url];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

NSError *error;
NSURLResponse *response;
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];


NSArray *gifs = [data objectForKey:@"data"];        


for (int i = 0; i < 1; i++) { // try to load 1 gif
    NSString *currentGifURL = @"whatever";

    // I tried using these 2 lines, still didn't work
    //[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
    NSURL *imageURL = [NSURL URLWithString:currentGifURL];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    NSImage *image = [[NSImage alloc] initWithData:imageData];

    [self performSelectorOnMainThread:@selector(LoadImageView:) withObject:image waitUntilDone:NO];

}        
    [_progressIndicator stopAnimation:self];
}
-(void)LoadImageView : (NSImage *)image
{
     NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
     imgView.image = image;
     [_scrollView.documentView addSubview:imgView];
}
于 2013-06-14T06:38:55.697 回答