Pregunta

The following code runs great and gives me the results I am looking for. However, I would like to run it in its own thread. Is MPMediaQuery thread safe, and what am I doing wrong, if it is?

-(NSArray*) mediaItemsFromPersistentIds:(NSArray*) mediaPersistentIds
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }

       MPMediaQuery *mediaQuery = [MPMediaQuery new];
       NSArray *itemsmediaQuery = mediaQuery.items;
       NSPredicate *predicate   = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", mediaPersistentIds];

    return [itemsmediaQuery filteredArrayUsingPredicate:predicate];
}

When I try the following, I get

Terminating app due to uncaught exception 'MPMediaItemCollectionInitException', reason: 'items array must not be empty'

I know the [itemsmediaQuery filteredArrayUsingPredicate:predicate] is being returned as (null)

-(NSArray*) mediaItemsFromPersistentIds:(NSArray*) mediaPersistentIds
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }
    __block NSArray *itemsmediaQuery;
    __block NSPredicate *predicate;

    dispatch_queue_t mediaQueryQueue = dispatch_queue_create("media query", NULL);
    dispatch_async(mediaQueryQueue, ^{

        MPMediaQuery *mediaQuery      = [MPMediaQuery new];
        itemsmediaQuery = mediaQuery.items;
        predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", mediaPersistentIds];

    });

    return [itemsmediaQuery filteredArrayUsingPredicate:predicate];
}
¿Fue útil?

Solución

It is safe to request these items in the background.

Right now, you're not actually running the query in the background. You could do something like this:

- (void)mediaItemsFromPersistentIds:(NSArray*)ids
                           callback:(void (^)(NSArray *items))callback {
    dispatch_queue_t mediaQueryQueue = dispatch_queue_create("media query", NULL);
    dispatch_async(mediaQueryQueue, ^{
        MPMediaQuery *mediaQuery = [MPMediaQuery new];
        itemsmediaQuery = mediaQuery.items;
        predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"itemId", ids];

        // Do the query
        NSArray *items = [itemsmediaQuery filteredArrayUsingPredicate:predicate];

        // Post the query results to the main thread in some way
        dispatch_async(dispatch_get_main_queue(), ^{
            // You could pass this off to a delegate or callback block
            if (callback)
                callback(items);
        });
    });
}

And to call it:

NSArray *ids = ...
[someObj mediaItemsFromPersistentIds:ids callback:^(NSArray *items) {
    // Do something with `items`
}];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top