Ios NSMutable数组属性在函数退出后变为null

Ios NSMutable数组属性在函数退出后变为null,ios,objective-c,json,Ios,Objective C,Json,我试图从一个JSON请求中获取CLLocation数组的值,并将它们分配给一个NSMutable数组属性。 此处显示相关控制器代码: - (void)viewDidLoad { [super viewDidLoad]; //using a background thread to receive the json call so that the UI doesn't stall dispatch_async(directionQueue, ^{ NSDa

我试图从一个JSON请求中获取CLLocation数组的值,并将它们分配给一个NSMutable数组属性。 此处显示相关控制器代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //using a background thread to receive the json call so that the UI doesn't stall
    dispatch_async(directionQueue, ^{
        NSData* data = [NSData dataWithContentsOfURL:openMapURL];
        [self performSelectorOnMainThread:@selector(fetchedData:)
                               withObject:data waitUntilDone:YES];
    });

    NSLog(@"%@", self.coordinates);
}

- (void)fetchedData:(NSData *)responseData 
{
    //parse out the json data
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:responseData //turn the data from the json request into a gigantic dictionary
                                     options:0
                                       error:&error];

    NSDictionary* route = [json objectForKey:@"route"]; //created a dictionary out of the contents of route
    NSDictionary* shape = [route objectForKey:@"shape"]; //create a sub-dictionary with the contents of shape
    NSArray* shapePoints = [shape objectForKey:@"shapePoints"]; //turn shapePoints object into an NSArray

    //Loop to turn the array of coordinate strings into CLLocation array
    NSMutableArray* locations = [[NSMutableArray alloc] init];
    NSUInteger i;
    for (i = 0; i < ([shapePoints count])/2 ; i = i+2) 
    {
        [locations addObject: [[CLLocation alloc]
                               initWithLatitude:[[shapePoints objectAtIndex:i] floatValue]
                               longitude:[[shapePoints objectAtIndex:i+1] floatValue]
                               ]];
    }

    //When I NSLog within the function, the array has the correct data. But in viewDidLoad
    //the array is null
    [self.coordinates initWithArray:locations copyItems:YES];   
}
-(void)viewDidLoad
{
[超级视图下载];
//使用后台线程接收json调用,以便UI不会暂停
调度异步(directionQueue^{
NSData*data=[NSData dataWithContentsOfURL:openMapURL];
[self-performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
NSLog(@“%@”,自身坐标);
}
-(void)获取数据:(NSData*)响应数据
{
//解析出json数据
n错误*错误;
NSDictionary*json=[NSJSONSerialization
JSONObjectWithData:responseData//将json请求中的数据转换成一个巨大的字典
选项:0
错误:&错误];
NSDictionary*route=[json objectForKey:@“route”];//使用route的内容创建了一个字典
NSDictionary*shape=[route objectForKey:@“shape”];//创建包含shape内容的子字典
NSArray*shapePoints=[shape objectForKey:@“shapePoints”];//将shapePoints对象转换为NSArray
//循环将坐标字符串数组转换为CLLocation数组
NSMUTABLEARRY*位置=[[NSMUTABLEARRY alloc]init];
NSUI;
对于(i=0;i<([shapePoints count])/2;i=i+2)
{
[位置添加对象:[[CLLocation alloc]
initWithLatitude:[[shapePoints对象索引:i]floatValue]
经度:[[shapePoints对象索引:i+1]floatValue]
]];
}
//当我在函数中NSLog时,数组有正确的数据
//数组为空
[self.coordinationinitwitharray:locations copyItems:YES];
}

为什么这个数组在viewDidLoad中变为空?

您正在使用GCD发出异步请求,从
viewDidLoad
方法获取数据。由于它是异步的,因此不会阻止
viewDidLoad
方法。一旦异步请求下载并被解析,数组就会被填充。这就是数组在
viewDidLoad
中为
nil
的原因

如果在数据下载并填充阵列之前,UI看起来是空白的,则可以选择显示活动指示器。这将让应用程序用户了解某些活动正在进行


希望有帮助

您正在使用GCD发出异步请求,从
viewDidLoad
方法获取数据。由于它是异步的,因此不会阻止
viewDidLoad
方法。一旦异步请求下载并被解析,数组就会被填充。这就是数组在
viewDidLoad
中为
nil
的原因

如果在数据下载并填充阵列之前,UI看起来是空白的,则可以选择显示活动指示器。这将让应用程序用户了解某些活动正在进行


希望有帮助

可能您需要做的是等待进程完成,而块实际上不知道您在其中做什么,或者我会说块没有捕获内部函数。因此,只有在块完成后才使用数组(调用正在使用数组的函数)

- (void)fetchedData:(NSData *)responseData 
{
    //parse out the json data
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:responseData //turn the data from the json request into a gigantic dictionary
                          options:0
                          error:&error];

    NSDictionary* route = [json objectForKey:@"route"]; //created a dictionary out of the contents of route
    NSDictionary* shape = [route objectForKey:@"shape"]; //create a sub-dictionary with the contents of shape
    NSArray* shapePoints = [shape objectForKey:@"shapePoints"]; //turn shapePoints object into an NSArray

    //Loop to turn the array of coordinate strings into CLLocation array
    NSMutableArray* locations = [[NSMutableArray alloc] init];
    NSUInteger i;
    for (i = 0; i < ([shapePoints count])/2 ; i = i+2) 
    {
        [locations addObject: [[CLLocation alloc]
                               initWithLatitude:[[shapePoints objectAtIndex:i] floatValue]
                               longitude:[[shapePoints objectAtIndex:i+1] floatValue]
                               ]];
    }

    //When I NSLog within the function, the array has the correct data. But in viewDidLoad
    //the array is null

    [self.coordinates initWithArray:locations copyItems:YES];

可能您需要做的是等待进程完成,而块实际上不知道您在其中做什么,或者我会说块没有捕获内部函数。因此,只有在块完成后才使用数组(调用正在使用数组的函数)

- (void)fetchedData:(NSData *)responseData 
{
    //parse out the json data
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:responseData //turn the data from the json request into a gigantic dictionary
                          options:0
                          error:&error];

    NSDictionary* route = [json objectForKey:@"route"]; //created a dictionary out of the contents of route
    NSDictionary* shape = [route objectForKey:@"shape"]; //create a sub-dictionary with the contents of shape
    NSArray* shapePoints = [shape objectForKey:@"shapePoints"]; //turn shapePoints object into an NSArray

    //Loop to turn the array of coordinate strings into CLLocation array
    NSMutableArray* locations = [[NSMutableArray alloc] init];
    NSUInteger i;
    for (i = 0; i < ([shapePoints count])/2 ; i = i+2) 
    {
        [locations addObject: [[CLLocation alloc]
                               initWithLatitude:[[shapePoints objectAtIndex:i] floatValue]
                               longitude:[[shapePoints objectAtIndex:i+1] floatValue]
                               ]];
    }

    //When I NSLog within the function, the array has the correct data. But in viewDidLoad
    //the array is null

    [self.coordinates initWithArray:locations copyItems:YES];

这就是原因。我最终取消了线程,并在发出JSON请求后更新了视图。我最初创建了一个线程,以便在应用程序发出api请求时视图不会暂停。谢谢你!这就是原因。我最终取消了线程,并在发出JSON请求后更新了视图。我最初创建了一个线程,以便在应用程序发出api请求时视图不会暂停。谢谢你!你应该知道,这是一个相当幼稚的方法。更糟糕的是,还有潜在的崩溃。由于调用
performSelector
,并将参数waitUntilDone设置为
YES
,可能会发生崩溃。这是一个相当微妙的错误。首先,块将保留self,选择器也将保留self。在选择器完成之前,该块将保留
self
。现在,该块可能持有对self的最后一个强引用,它在块完成后最终被释放,
self
在辅助线程上被释放,这将崩溃,因为UIKit方法必须在主线程上执行。您应该知道,这是一种非常幼稚的方法。更糟糕的是,还有潜在的崩溃。由于调用
performSelector
,并将参数waitUntilDone设置为
YES
,可能会发生崩溃。这是一个相当微妙的错误。首先,块将保留self,选择器也将保留self。在选择器完成之前,该块将保留
self
。现在,块可能持有对self的最后一个强引用,它在块完成后最终被释放,而
self
在辅助线程上被释放,这将崩溃,因为UIKit方法必须在主线程上执行。