0

我正在开发一个应用程序,它与 RESTful 服务器联系以获取一些数据,然后使用返回的 JSON 响应来显示该数据。

使用 UniRest 调用,一切正常。主要调用是“runUnirestRequest”

uni rest 调用是一个异步 GCD 调度调用。我的问题是,因为我在本地进行测试,所以调用太快了,我看不到活动指示器滚动。它在我看到它之前就消失了。

GCD 块发生在 viewController viewDidLoad 调用中。

我需要实现的目标:让异步 unirest 调用需要几秒钟来模拟缓慢的服务器响应(不想真正停止 iOS 应用程序的运行)。

请原谅任何编码错误/坏习惯,只做了一周的目标 c,但很高兴有任何额外的建设性批评。:)

我努力了

sleep(5); // But bad idea as far as I can see.

也试过

[NSThread sleepForTimeInterval:5.0]; // but this doesn't seem to do anything.

viewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self createActivityIndicator];

    NSLog(@"viewDidLoad");
    NSLog(@"viewDidLoad->thread: %@", [NSThread currentThread]);
    [messageLabel setText:@""];

    unirestQueue = dispatch_queue_create("com.simpleweb.pbs.dayDataUnirestRequest", NULL);

    // Do any additional setup after loading the view from its nib.
    daySalesFigures = [[PBSDaySales alloc] init];
    responseVal = [[HttpJsonResponse alloc] init];

    // Use Grand Central Dispatch to run async task to server
    dispatch_async(unirestQueue, ^{
        [self runUnirestRequest:self.requestUrl];

    });

    dispatch_after(unirestQueue, dispatch_get_main_queue(), ^(void){
        [activityIndicator stopAnimating];
    });
}

runUniRestRequest 函数

- (void) runUnirestRequest:(NSString*)urlToGet
{
    [NSThread sleepForTimeInterval:5.0];

    NSLog(@"runUnirestRequest called");

    HttpJsonResponse* response = [[Unirest get:^(SimpleRequest* request) {
        [request setUrl:@"http://x.x.x.x:9000/Sales/Day/2013-02-14"];
    }] asString];

    NSString *jsonStr = [response body];

    SBJsonParser *jsonParser = [SBJsonParser new];

    id response2 = [jsonParser objectWithString:jsonStr];
    [self deserializeJsonPacket:(NSDictionary*)response2];

}
4

1 回答 1

3

dispatch_after的第一个参数是时间。您正在传递unirestQueue,这是dispatch_queue_t根据队列

unirestQueue = dispatch_queue_create("com.simpleweb.pbs.dayDataUnirestRequest", NULL);

的正确代码dispatch_after,即在一些延迟后执行块,是这样的:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    //  Do whatever you want
});

编辑:哦,我可能看到你想要完成的事情:-) 你认为这dispatch_after意味着“在这个队列之后做点什么”对吗?不,它是“一段时间后做某事”

编辑 2:您可以使用如下代码在后台执行一些耗时的操作,并在完成后更新 UI

//  Start block on background queue so the main thread is not frozen
//  which prevents apps UI freeze
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //  Do something taking a long time in background
    //  Here we just freeze current (background) thread for 5s
    [NSThread sleepForTimeInterval:5.0];

    //  Everything in background thread is done
    //  Call another block on main thread to do UI stuff
    dispatch_async(dispatch_get_main_queue(), ^{
        //  Here you are in the main thread again
        //  You can do whatever you want
        //  This example just stops UIActivityIndicatorView
        [activityIndicator stopAnimating];
    });
});

编辑 3:我在 raywenderlich.com 上推荐这篇关于 GCD 的精彩文章以获取更多详细信息

于 2013-09-16T14:09:10.067 回答