【问题标题】:Class array object value always return nil after json serializationjson序列化后类数组对象值总是返回nil
【发布时间】:2020-02-29 20:36:21
【问题描述】:

我创建了一个名为“GetDataFromURL”的函数,它的主要任务是获取数据表单 URL 并存储到本地类数组对象中。 使用 URlSession.shared.dataTask 函数我将数据接收为 DATA 格式,然后通过使用 jsonserialization.jsonObject 方法我进入 json 格式。响应是字典格式,因此存储到临时类对象中,最后它将附加到全局类数组对象中。这个函数被调用,而 Page 被称为“View Load”方法。在函数内,它将显示所有数据,但每次我在块外显示时得到 nil 数组对象。

public class Modelclass : NSObject {

var id :Int!
var albumId : Int!
var title : String!
var url : String!
var thumbnailUrl : string! 

}

这是 Class 文件,下面是 viewcontroller 文件:

var temp:[ModelClass]? 

override func viewDidLoad() {

super.viewDidLoad()
self.temp = [ModelClass]()
dispatchQueue.main.async{
    self.GetDataFromURL()
}

print(self.temp,"Tesing print")
}



  func GetDatafromURL() {

  if let url = URL(string : 
  "https://jsonplaceholder.typicode.com/photos"){
   URLSession.shared.dataTask(with: url){(data,response,error) in
    if error != nil {
        print(error)
        return
    }
    do{
        let jsonresponse = try jsonserialization.jsonObject(with:data! , 
        options: .mutablecontainers)
        for dictionary in jsonresponse as! [[String:AnyObject]]
        {
            var test = ModelClass()
            test.title = dictionary["title"] as? String
            test.albumId = dictionary["albumId"] as? Int
            test.id = dictionary["id"] as? Int
            test.thumbnailUrl = dictionary["thumbnailUrl"] as? String
            test.url = dictionary["url"] as? String
            self.temp?.append(test)
        }

    }
    catch let jsonerror{
        print(jsonerror)
    }
 }.resume()
}
}

它向我显示“ optional([]) Tesing print ”作为输出。在 do 块中打印该临时对象时,它将显示所有数据。

【问题讨论】:

  • 您正在进行异步调用,当执行该打印时,您的下载尚未完成。您应该考虑为您的 GetDatafromURL 添加一个闭包
  • 您还应该考虑到您的print 调用打印了self.temp 和内部GetDatafromURL 函数,您将附加到test.temp 而不是self.temp
  • Octavin Marculescu,我写错了。请检查我更新了一个。

标签: ios json swift nsurlsession nsjsonserialization


【解决方案1】:

// 添加这个 var dispatchgroup = DispatchGroup() //

var temp: [Modelclass] = []

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.


    self.GetDatafromURL()

    //Add this
    dispatchgroup.notify(queue: .main){
         print("temp data : \(self.temp.count)")
    }

}



  func GetDatafromURL() {

    //add this
    dispatchgroup.enter()
    //

  if let url = URL(string :
  "https://jsonplaceholder.typicode.com/photos"){
   URLSession.shared.dataTask(with: url){(data,response,error) in
    if error != nil {
        print(error)
        return
    }
    do{


        let jsonresponse = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)

        for dictionary in jsonresponse as! [[String:AnyObject]]
        {
            var test = Modelclass()
            test.title = dictionary["title"] as? String
            test.albumId = dictionary["albumId"] as? Int
            test.id = dictionary["id"] as? Int
            test.thumbnailUrl = dictionary["thumbnailUrl"] as? String
            test.url = dictionary["url"] as? String
            self.temp.append(test)
        }

          //add this
        self.dispatchgroup.leave()
        //


    }
    catch let jsonerror{
        print(jsonerror)
    }
 }.resume()
}

}

【讨论】:

  • 您在滥用DispatchGroup。请不要那样做。
【解决方案2】:

这里是目标 c 的版本,

   @property (strong,nonatomic) NSMutableArray<UserModel *> *jsonarray ;
   @end

   @implementation ViewController

   dispatch_group_t serviceGroup;
   NSMutableDictionary *result ;


  - (void)viewDidLoad {
   [super viewDidLoad];
   // Do any additional setup after loading the view, typically from a nib.

    result = [[NSMutableDictionary alloc]init];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;

     UINib *nib = [UINib nibWithNibName:@"TableViewCell" bundle:nil];
    [self.tableView registerNib:nib forCellReuseIdentifier:@"TableViewCell"];
    serviceGroup = dispatch_group_create();


    _jsonarray = [[NSMutableArray alloc]init];

// \ [userdata GetDatafromUrl:@"https://jsonplaceholder.typicode.com/users"];

    [self GEtDataFromurl:@"https://jsonplaceholder.typicode.com/users"];
    }



 -(void)GEtDataFromurl:(NSString *) urlstr{

 dispatch_group_enter(serviceGroup);
[[NSURLSession.sharedSession dataTaskWithURL:[NSURL URLWithString:urlstr] completionHandler:^(NSData *_Nullable data,NSURLResponse *_Nullable response, NSError *_error){
    NSError *err;
    NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
    if(err){
        NSLog(@"Falied to serialization.. ");
        return;
    }

    for (NSDictionary *UserDir in json){
        NSString *Id = UserDir[@"id"] ;
        NSString *name = UserDir[@"name"] ;
        NSString *username = UserDir[@"username"];
        NSString *email = UserDir[@"email"];
        NSString *phone = UserDir[@"phone"];
        NSString *website = UserDir[@"website"];

        struct company *company = CFBridgingRetain(UserDir[@"company"]);
        struct address *address = CFBridgingRetain(UserDir[@"address"]);

        UserModel *model = UserModel.new;
        model.Id =  [Id intValue];
        model.name = name;
        model.address = address;
        model.username = username;
        model.email  = email;
        model.phone = phone;
        model.website = website;
        model.company = company;
        NSLog(@"%@", model.name);
        [_jsonarray addObject:model];

    }
            dispatch_group_leave(serviceGroup);
}]resume];

dispatch_group_notify(serviceGroup,dispatch_get_main_queue(),^{


    NSLog(@" outside user class :  %@", _jsonarray);

    [self.tableView reloadData];
});

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 返回 1; }

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewCell" forIndexPath:indexPath];
if(cell == nil){
    NSArray *obj = [[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:self options:nil];
    cell = [obj objectAtIndex:0];
}
UserModel *model = _jsonarray[indexPath.row];
cell.displaylabel.text = model.username;

return  cell;

}

- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:                (NSInteger)section {
 return _jsonarray.count;

}

@结束

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多