Как нацелиться на родительский объект при использовании executeSelectorOnMainThread? - PullRequest
0 голосов
/ 13 марта 2012

У меня есть пользовательский объект NSOperation, который создается из подкласса UITableViewController (MusicTableVC). Предполагается, что объект NSOperation заполняет NSarray из URL в фоновом режиме, чтобы пользовательский интерфейс не зависал, но затем мне нужно отправить этот массив обратно в основной поток, чтобы экземпляр MusicTableVC мог что-то с ним делать. Я знаю, что мне нужно использовать executeSelectorOnMainThread: для отправки массива обратно в MusicTableVC, но для этого мне нужен указатель на экземпляр MusicTableVC.

Я думал о создании метода init в NSOperation, например. initWithParent передать указатель на себя и использовать его, но, может быть, я что-то упустил?

@synthesize parent;

- (id)initWithParent:(MusicTableVC*) musicTableViewController
{
    if(self = [super init])
    {
        self.parent = musicTableViewController;
    }
    return self;
}

-(void) main
}
[parent performSelectorOnMainThread:@selector(arrayFinishedLoading:)
                                           withObject:playlist
                                        waitUntilDone:YES];

}

Ответы [ 3 ]

1 голос
/ 13 марта 2012

Я думаю, вы бы лучше справились с блоками и Grand Central Dispatch:

dispatch_async(dispatch_get_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0), ^{
    // This is called in background, not blocking the UI
    [self populateArrayFromURL];
    dispatch_async(dispatch_get_main_queue(), ^{
        // This is called on the main thread
        [self reportStuffDone];
    });
});
0 голосов
/ 13 марта 2012

С тобой все в порядке, я бы назвал его initWithDelegate и определил бы протокол.Просто передайте делегат, и тогда операция будет завершена, просто узнайте, успешно ли это выполнено.

Недавно я переключался с бесполезных делегатов на GCD, поэтому вместо этого я сделал бы что-то вроде initWithSuccessBlock и затем отправил бы егов основную очередь.Обратите внимание, что если вы решите использовать это, вам нужно будет убедиться, что блок был скопирован.

0 голосов
/ 13 марта 2012

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

NSOperation *myOp = [[NSOperation alloc] init];
[myOp addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionsNew context:NULL];

, затем добавьте метод обратного вызова KVO:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSOperation *myOp = (NSOperation *)object;
    [myOp removeObserver:self forKeyPath:keyPath];
    dispatch_async(dispatch_get_main_queue(), ^{
         // reload the table with the results here
    });
}
...