iOS segue太慢了

Uma*_*Uma 3 profiler objective-c uistoryboardsegue

我开始使用iOS.并使用Storyboard在视图控制器之间导航.第一个屏幕是uiviewcontroller(登录屏幕),第二个屏幕是带有表格视图的uiviewcontroller.我在第一个viewcontroller中发送一些Web请求,然后执行segue到下一个viewcontroller.获得响应后,加载第二个视图控制器有大约9秒的延迟.我尝试使用Timer profiler检查原因,并且没有在我的obj-c代码中找到任何内容.

如果有人可以帮助我这里是我的跟踪文件的链接.

我的日志:

2014-05-08 10:12:12.601 Consumer[6713:4207] One 2014-05-08 10:12:12.602 Consumer[6713:4207] Three 2014-05-08 10:12:12.605 Consumer[6713:4207] Four 2014-05-08 10:12:12.606 Consumer[6713:4207] Two 2014-05-08 10:12:21.394 Consumer[6713:60b] numberOfSectionsInTableView 2014-05-08 10:12:21.395 Consumer[6713:60b] titleForHeaderInSection 2014-05-08 10:12:21.395 Consumer[6713:60b] numberOfRowsInSection 2014-05-08 10:12:21.395 Consumer[6713:60b] titleForHeaderInSection 2014-05-08 10:12:21.395 Consumer[6713:60b] numberOfRowsInSection 2014-05-08 10:12:21.396 Consumer[6713:60b] titleForHeaderInSection 2014-05-08 10:12:21.396 Consumer[6713:60b] numberOfRowsInSection 2014-05-08 10:12:21.396 Consumer[6713:60b] cellForRowAtIndexPath 2014-05-08 10:12:21.399 Consumer[6713:60b] returning cell 2014-05-08 10:12:21.399 Consumer[6713:60b] cellForRowAtIndexPath 2014-05-08 10:12:21.400 Consumer[6713:60b] returning cell 2014-05-08 10:12:21.401 Consumer[6713:60b] cellForRowAtIndexPath 2014-05-08 10:12:21.402 Consumer[6713:60b] returning cell 2014-05-08 10:12:21.402 Consumer[6713:60b] titleForHeaderInSection

我的LoginViewController:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"login_success_new"]){
    TableViewController *controller = (TableViewController *)segue.destinationViewController;
    controller.municipalitiesArray = municipalitiesArray;
    controller.muni_metergroup_dict = muni_metergroup_dict;
    NSLog(@"Three");
}
}

-(void) sendPostRequest:(NSURL *)requestURL requestParams:(NSDictionary *)params requestType:(NSInteger)type{
NSError *error;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPMethod:@"POST"];

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
[request setHTTPBody:postData];


NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSLog(@"response = %@",json);


    if(json != nil){
        switch (type) {
            case 1:
            {

                for (NSObject *object in [json objectForKey:@"municipalities"]){
                    MunicipalityModel *muniModel = [[MunicipalityModel alloc] init];
                    [muniModel setModelValues:object];
                    [municipalitiesArray addObject:muniModel];
                }
                //municipalitiesArray = [json objectForKey:@"municipalities"];
                //MunicipalitiesModel *muniModel = [[MunicipalitiesModel alloc] init];
                //[muniModel setModelValues:municipalitiesArray[0]];
                userEmail = @"admin@example.com";
                tokenValue = [json objectForKey:@"token"];
                NSString *stringUrl = [NSString stringWithFormat:@"http://%@.quality.sentry-link.com/api/v1/meter_groups.json",[municipalitiesArray[count] muniSubdomain]];
                NSURL *url = [NSURL URLWithString:stringUrl];
                [self sendGetRequest:url requestParams:nil requestType:2];

                break;
            }
            default:
                break;
        }
        //[self performSegueWithIdentifier:@"login_success" sender:self];
    }
}];

[postDataTask resume];

}

-(void) sendGetRequest:(NSURL *)requestURL requestParams:(NSDictionary *)params requestType:(NSInteger)type{

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"GET"];

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

NSLog(@"Request URL =====> %@",requestURL);

NSURLSessionDataTask *getDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSLog(@"response = %@",json);


    if(json != nil){
        switch (type) {
            case 1:
            {
                break;
            }
            case 2:
            {
                 NSMutableArray *meterGroupsArray = meterGroupsArray = [[NSMutableArray alloc] init];

                for (NSObject *object in [json objectForKey:@"meter_groups"]){
                    MeterGroupModel *meterGroupModel = [[MeterGroupModel alloc] init];
                    [meterGroupModel setModelValues:object];
                    [meterGroupsArray addObject:meterGroupModel];
                }
                count++;
                [muni_metergroup_dict setValue:meterGroupsArray forKey:[municipalitiesArray[count-1] muniSubdomain]];
                if (count < [municipalitiesArray count]) {
                    NSString *stringUrl = [NSString stringWithFormat:@"http://%@.quality.sentry-link.com/api/v1/meter_groups.json",[municipalitiesArray[count] muniSubdomain]];
                    NSURL *url = [NSURL URLWithString:stringUrl];
                    [self sendGetRequest:url requestParams:nil requestType:2];
                }
                break;
            }

            default:
                break;
        }
        if(count ==[municipalitiesArray count]){
            NSLog(@"One");
            [self performSegueWithIdentifier:@"login_success_new" sender:self];
            NSLog(@"Two");
        }

    }
}];

[getDataTask resume];
}
Run Code Online (Sandbox Code Playgroud)

TableviewController:

- (void)viewDidLoad
{
[super viewDidLoad];
//tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
NSLog(@"Four");
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)buttonClicked:(id)sender{
NSLog(@"button Clicked");
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
NSLog(@"numberOfSectionsInTableView");
return [_municipalitiesArray count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//Number of rows it should expect should be based on the section

NSString *sectionSubdomain = [_municipalitiesArray[section] muniSubdomain];
NSArray *array = [_muni_metergroup_dict objectForKey:sectionSubdomain];
NSLog(@"numberOfRowsInSection");
return [array count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSLog(@"titleForHeaderInSection");
return [self.municipalitiesArray [section] muniName];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"cellForRowAtIndexPath");
long row = [indexPath row];
long section = [indexPath section];
NSArray *meterGroupArray = [_muni_metergroup_dict valueForKey:[_municipalitiesArray[section] muniSubdomain]];
static NSString *CellIdentifier = @"tableCell";

TableViewCell *cell = [tableView
                          dequeueReusableCellWithIdentifier:CellIdentifier
                          forIndexPath:indexPath];

// Configure the cell...

[cell.lblMeterGroupName setText:[meterGroupArray[row] groupName]];
[cell.lblMeterGroupId setText:[meterGroupArray[row] groupId]];
[cell.lblLatitude setText:[meterGroupArray[row] latitude]];
[cell.lblLongitude setText:[meterGroupArray[row] longitude]];



NSLog(@"returning cell");
return cell;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

mat*_*att 7

在您的日志中清楚地显示的问题是在后台线程上执行一,二,三和四.这意味着,例如,您说:

[self performSegueWithIdentifier:@"login_success_new" sender:self];
Run Code Online (Sandbox Code Playgroud)

...在后台线程上.那是错的.你不能对后台线程上的接口说什么或者说什么.你需要让你的线程理顺.(一,二,三和四不按顺序发生的事实也是一个线索,你可能已经非语言地设置了它.)

编辑:在评论中,你说你现在使用dispatch_async(dispatch_get_main_queue()...,因此正确地将调用移动performSegueWithIdentifier:到主线程.优秀!您的日志记录现在应该显示与接口连接的所有呼叫(尤其是"三个" prepareForSegue:)现在都在主线程上.

但是,你仍然需要小心.基本上两个completion:处理程序中的所有内容都发生在后台线程上!你甚至在调用[self sendGetRequest:...]后台线程!而你显然正在讨论self这个后台线程的实例变量.所有这一切都很危险.我要做的是每个completion处理程序的开头直接进入主线程,这样即使在后台线程上调用完成处理程序,我所做的一切都发生在主线程上.