user73171
user73171

Reputation: 95

GIFs don't animate when using NSThread

I'm writing an application in Objective C and Cocoa for Mac OS X that loads GIFs from an external source and displays them on screen. The user searches for a term, GIFs are downloaded and placed into NSImageViews, and then those views are displayed in a scroll view.

Earlier, the GIFs were animated as expected. I then tried to use an NSThread to do the loading of the GIFs and adding to the scroll view separate from the main thread. Here is the method that is called in the thread:

    - (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];
}

I later call

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

To create the thread. The images appear on screen, but only the first frame is displayed—they're not animated. Literally replacing the thread initialization with the code from inside the thread renders the same view, except the GIFs are animated. Is there something about threads that would prevent the GIFs from animating?

Thanks!

Upvotes: 1

Views: 301

Answers (1)

Parag Bafna
Parag Bafna

Reputation: 22930

NSImageView is not threadsafe. use - (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];
}

Upvotes: 1

Related Questions