Objective c 如何在使用performSelectorOnMainThread时以父对象为目标?

Objective c 如何在使用performSelectorOnMainThread时以父对象为目标?,objective-c,ios,nsoperation,Objective C,Ios,Nsoperation,我有一个自定义NSOperation对象,它是从UITableViewController子类(MusicTableVC)实例化的。NSOperation对象应该从后台的URL填充一个NSarray,这样UI就不会冻结,但是我需要将该数组发送回主线程,以便MusicTableVC实例可以处理它。 我知道我需要使用performSelectorOnMainThread:将数组发送回MusicTableVC,但要做到这一点,我需要一个指向MusicTableVC实例的指针 我在考虑在NSOperat

我有一个自定义NSOperation对象,它是从UITableViewController子类(MusicTableVC)实例化的。NSOperation对象应该从后台的URL填充一个NSarray,这样UI就不会冻结,但是我需要将该数组发送回主线程,以便MusicTableVC实例可以处理它。 我知道我需要使用performSelectorOnMainThread:将数组发送回MusicTableVC,但要做到这一点,我需要一个指向MusicTableVC实例的指针

我在考虑在NSOperation中创建一个init方法,例如initWithParent,以传递指向self的指针并使用它,但可能我遗漏了什么

@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];

}

我认为你最好使用blocks和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];
    });
});

这是一种方法,但更常见的模式是让
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
    });
}

您的方式很好,我将其称为initWithDelegate并定义一个协议。只需传递委托,然后操作就完成了,只需让它知道是否成功


最近,我一直在从无用的委托切换到GCD,所以我会制作类似于initWithSuccessBlock的东西,然后将其分派到主队列。请注意,如果您决定使用此功能,您必须确保该块已被复制。

GCD和块在iOS上都已可用很长时间了,您知道吗?不,实际上我不知道。我必须仔细阅读GDC,谢谢。