Как опубликовать NSNotification при использовании Grand Central Dispatch? - PullRequest
3 голосов
/ 06 октября 2011

Я обнаружил, что, как и предсказывалось, когда я записывал изображение в файл, мой пользовательский интерфейс был заблокирован на время, что было неприемлемо. Когда я записываю изображение в файл, я публикую NS-уведомление, чтобы я мог выполнять некоторые другие специфические задания, связанные с этим завершением. Оригинальный рабочий, но код блокировки интерфейса:

-(void)saveImageToFile {
    NSString *imagePath = [self photoFilePath];
    BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES];

if (jpgData) {        
    [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self];
}

Чтобы избежать блокировки пользовательского интерфейса, я поместил writeToFile: в очередь Grand Central Dispatch, чтобы она работала как параллельный поток. Но когда запись завершена и поток завершен, я хочу опубликовать NSNotification. Я не могу, так как код показан здесь, потому что он находится в фоновом потоке. Но это та функция, которую я хочу реализовать, понимая, что это не выполнимый код:

-(void)saveImageToFile {
    NSString *imagePath = [self photoFilePath];

    // execute save to disk as a background thread
    dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0);
    dispatch_async(myQueue, ^{
        BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (jpgData) {        
            [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self];
            }
        });
    });
}

Каков правильный механизм отправки этого уведомления для получения желаемой функциональности?

Ответы [ 2 ]

6 голосов
/ 06 октября 2011

Пара возможностей здесь.

1)

Как насчет [NSObject executeSelectorOnMainThread: ...]?

EG

-(void) doNotification: (id) thingToPassAlong
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:thingToPassAlong];
}

-(void)saveImageToFile {
    NSString *imagePath = [self photoFilePath];

    // execute save to disk as a background thread
    dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0);
    dispatch_async(myQueue, ^{
        BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (jpgData) {   
                [self performSelectorOnMainThread: @selector(doNotification:) withObject: self waitUntilDone: YES];
            }
        });
    });
}

Подробнееподробности на http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:

или 2)

Обратные вызовы завершения

, как видно на Как я могу получить уведомление о завершении задачи dispatch_async?

1 голос
/ 02 июня 2012
-(void)saveImageToFile {
    NSString *imagePath = [self photoFilePath];

    // execute save to disk as a background thread
    dispatch_queue_t myQueue = dispatch_queue_create("com.wilddogapps.myqueue", 0);
    dispatch_async(myQueue, ^{
        BOOL jpgData = [UIImageJPEGRepresentation([[self captureManager] stillImage], 0.5) writeToFile:imagePath atomically:YES];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (jpgData) {        
            [[NSNotificationCenter defaultCenter] postNotificationName:kImageSavedSuccessfully object:self];
            }
        });
    });
}

Это уже правильно.Однако зачем вам использовать уведомление, если вы уже отправили dispatch_get_main_queue ()?

Просто используйте

        dispatch_async(dispatch_get_main_queue(), ^{
            if (jpgData) {        
            //Do whatever you want with the image here
            }
        });

В любом случае, ваше оригинальное решение в порядке.Это не блокировка.По сути, он сохранит файл в другом потоке, и как только это будет сделано, он будет делать то, что нужно.

Все, что вы делаете, будет сделано в том же потоке с потоком, который вызывает [[NSNotificationCenter defaultCenter] postNotificationName: kImageSavedSuccessfully объект: self];а именно основная нить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...