异步多项

时间:2013-07-01 22:13:47

标签: ios asynchronous dialog

因此,我通常会为Android编写应用程序,只需使用异步任务调用方法在后台运行,同时警告对话框会显示“正在加载”或类似内容。在这个应用程序我试图翻译到iOS,我解析来自不同网站的数据,并显示几个网络图像,我想让我的alart对话框播放,而所有这些东西都被加载。我一直在寻找几个小时,并没有找到我正在寻找的解决方案。我希望有人可以指点我的教程或正确的方向。

这是我正在使用的:

- (void) RSEpic{
NSURL * imageURL = [NSURL URLWithString:RSEimageURL];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
_RSEImage.image = image;
[self waterTemp];
}

- (void) waterTemp{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
/* set headers, etc. on request if needed */
[request setURL:[NSURL URLWithString:@"http://waterdata.usgs.gov/usa/nwis/uv?02035000"]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL       error:NULL];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:html];
NSString *token = nil;
[scanner scanUpToString:@"<table id=\"table_12_00010\"" intoString:NULL];
[scanner scanUpToString:@"&nbsp" intoString:&token];
NSArray *words = [token componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":"]];
double temp = [words[1] doubleValue];
_waterTempC.Text = [NSString stringWithFormat:@"%.2f°C",temp];
_waterTempF.Text = [NSString stringWithFormat:@"%.2f°F",temp*9/5+32];
[self waterDepth];
}

- (void) waterDepth{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
/* set headers, etc. on request if needed */
[request setURL:[NSURL URLWithString:@"http://waterdata.usgs.gov/va/nwis/uv?02037500"]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:html];
NSString *token = nil;
[scanner scanUpToString:@"<table id=\"table_07_00065\"" intoString:NULL];
[scanner scanUpToString:@"&nbsp" intoString:&token];
NSArray *words = [token componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":"]];
double temp = [words[1] doubleValue];
_waterLevel.Text = [NSString stringWithFormat:@"%.2fFT",temp];
if (temp >= 9.0) {
    _levelAlert.text = @"HIGH WATER PERMIT REQUIRED";
    }
else if (temp >= 5.0){
    _levelAlert.text = @"LIFE JACKET REQUIRED";
}
else {
    _levelAlert.text = @"";
}
[self tempChart];
}

- (void) tempChart{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
/* set headers, etc. on request if needed */
[request setURL:[NSURL URLWithString:@"http://waterdata.usgs.gov/nwis/uv/?dd_cd=12_00010&format=img_default&site_no=02035000&set_arithscale_y=on&period=7"]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:html];
NSString *token = nil;
[scanner scanUpToString:@"http" intoString:NULL];
[scanner scanUpToString:@"\"" intoString:&token];
NSLog(@"%@",token);
NSURL * imageURL = [NSURL URLWithString:token];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
_chartImage.image = image;
}

- (void) depthChart{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
/* set headers, etc. on request if needed */
[request setURL:[NSURL URLWithString:@"http://waterdata.usgs.gov/va/nwis/uv/?dd_cd=07_00065&format=img_default&site_no=02037500&set_arithscale_y=on&period=7"]];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:html];
NSString *token = nil;
[scanner scanUpToString:@"http" intoString:NULL];
[scanner scanUpToString:@"\"" intoString:&token];
NSLog(@"%@",token);
NSURL * imageURL = [NSURL URLWithString:token];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
_chartImage.image = image;
}

- (void) progressAlert {
// initialize our Alert View window without any buttons
baseAlert=[[UIAlertView alloc]initWithTitle:@"Please wait,\ndownloading updates...." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil];

// Display our Progress Activity view
[baseAlert show];

// create and add the UIActivity Indicator
UIActivityIndicatorView
*activityIndicator=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.center=CGPointMake(baseAlert.bounds.size.width
                                     / 2.0f,baseAlert.bounds.size.height-40.0f);

// initialize to tell our activity to start animating.
[activityIndicator startAnimating];
[baseAlert addSubview:activityIndicator];

// automatically close our window after 3 seconds has passed.
[self performSelector:@selector(showProgressDismiss)withObject:nil afterDelay:3.0f];

}
- (void) showProgressDismiss
{
[baseAlert dismissWithClickedButtonIndex:0 animated:NO];
}
@end

所有人都可以告诉我如何在所有这些东西加载时进行我的baseAlert Show和Dismiss?

3 个答案:

答案 0 :(得分:2)

使用dispatch_group_t,一旦完成所有线程,他们就可以调用notify,如下所示:

        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self doAnExpensiveOperation];
        });
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self doAnotherExpensiveOperation];
        });
        dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{

            dispatch_async(dispatch_get_main_queue(), ^{

                // called when both background threads have finished.
                // Update UI elements here
            });

        });

优先顺序:

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            [self doAnotherExpensiveOperation];
        });

答案 1 :(得分:0)

同样的概念应用于iOSAndroid:如果你想执行繁重的计算,并且你希望应用程序能够响应,请在后台线程上执行繁重的计算并且不要执行UI来自背景线索。 iOSAndroid之间的唯一区别是您可以在后台线程上执行任务的方式。 AndroidAsyncTasksLoadersiOSNSOperations&amp; NSOperationsQueueGCD(我最喜欢的盛大中央调度,也是我认为最好的解决方案),或者有performSelectorInBackground:这样的方法我不喜欢,因为之后很难返回对象线程完成。

所以我的建议是,查看GCD(还有很多其他教程),之后,相应地更改代码,如果您在更改代码时遇到麻烦或者有意外行为,请回过头来与其他问题一样

答案 2 :(得分:0)

嗯,为了简单明了,你可以告诉你的操作系统用另一个线程执行一些代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Insert your code here
});

全局队列意味着您将向GCD提交一个块,并且OS将在一个方便的线程中执行该块,但主线程(您的UI运行的位置除外)。您必须注意,如果要更新UI(例如隐藏警报或停止活动指示符),则需要在主线程(main_queue)中执行此操作。因此,我们总是使用的模板如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Process your heavy code here.
    dispatch_async(dispatch_get_main_queue(), ^{
        //Update your UI here.
    });
});

如果您使用ARC

,这对于避免保留周期非常重要

正如Apple所说here,你必须在一个块内使用对self的弱引用,因为对于你的保留计数将增加的块中使用的任何iVar都是如此。

我建议@danypata提出的教程,这是一个很好的教程。在同一个站点中,您可以找到许多有用的教程!!

度过美好的一天,并希望它有所帮助!