从另一个线程在主线程上运行方法

6 cocoa nsthread

我的模型类必须从互联网上获取一些数据.所以我决定在另一个线程上运行它,所以ui不会冻结.因此,当一个对象想要一些数据时,它首先使用这种类型的方法询问模型:

- (void)giveMeSomeData:(id)object withLabel:(id)label {
objectAsking= object;
theLabel= label;
NSThread* thread= [[NSThread alloc] initWithTarget:self selector:@selector(getTheDataFromInternet) object:nil];
[thread start];
}

- (void)getTheDataFromInternet {
//getting data...

theData= [dataFromInternet retain]; //this is the data the object asked for
[self returnObjectToAsker];
}

- (void)returnObjectToAsker {
[objectAsking receiveData:theData withLabel:theLabel];
}
Run Code Online (Sandbox Code Playgroud)

因为我还是个新手,你能告诉我它是不是一个好模式?

谢谢!

Dav*_*ong 12

您的设置非常正确.您永远不想在主线程上启动任何类型的网络连接.

目前的情况是,-returnObjectToAsker将在后台线程上执行.

你可能会感兴趣-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:].

或者,如果您想要使用Grand Central Dispatch(iOS 4 +,Mac OS X 10.6+),您可以:

#import <dispatch/dispatch.h>

- (void)giveMeSomeData:(id)object withLabel:(id)label {
    dispatch_async(dispatch_get_global_queue(0,0), ^{
      //this runs on a background thread
      //get data from the internet
      dataFromTheInternet = ...;
      dispatch_async(dispatch_get_main_queue(), ^{
        [object receiveData:dataFromTheInternet withLabel:label];
        //this runs on the main thread.  Use theData
      });
    });
}
Run Code Online (Sandbox Code Playgroud)

由于块捕获了它们的环境,你甚至不需要保存objectlabel进入ivars.:)

  • @Forchita如果我只能支持iOS 4或OS 10.6,那么我更喜欢使用GCD,因为我可以将所有逻辑保留在一个方法中. (2认同)