【问题标题】:NSArray is empty after sending data from my class to TableViewController将数据从我的班级发送到 TableViewController 后,NSArray 为空
【发布时间】:2014-06-15 21:00:26
【问题描述】:

我有一个继承自 NSObject 的 Data 类。
在这个课程中,我处理我的数据请求。
在此之后,我想将它保存在 NSMutableArray 中的数据发送到我的 UITableViewController。

我该如何解决这个问题?

@interface Data : NSObject

@property(nonatomic,strong) NSMutableArray *data;

-(NSMutableArray *) loadData;

-(id)init;

@end


@implementation Data

@synthesize data;

-(id)init {

    self = [super init];

    if(self){
        self.data = [[NSMutableArray alloc]init];
    }

    return self;

}

- (NSMutableArray *)loadData {


    NSString *url = @"http://localhost/xampp/flashbackapi/";

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {


        [data addObject:responseObject];


    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error %@",error);
    }];

    return data;

}

@end


#import <UIKit/UIKit.h>
#import "Club.h"
#import "Data.h"

@interface ClubsTableViewController : UITableViewController

@property(nonatomic,strong) Data *holderData;
@property(nonatomic,strong) NSMutableArray *teams;



@end

#import "AFNetworking.h"

@implementation ClubsTableViewController


    - (void)viewDidLoad
    {
        [super viewDidLoad];

        self.holderData = [[Data alloc]init];
        self.teams = [[NSMutableArray alloc]init];

        self.teams = self.holderData.loadData;

        NSLog(@"%@",self.teams); //this array is empty.. why? 



    }

【问题讨论】:

    标签: ios uitableview nsmutablearray nsurl nsurlrequest


    【解决方案1】:

    您的 loadData 方法正在返回一个永远不会包含您的 responseObject 内容的数据属性。这是因为您的 loadData 方法包含一个异步调用(对管理器 GET:parameters:success:)。当异步调用返回时,正在填充数据属性/ivar,在您的情况下为时已晚。一种解决方案是将 loadData 也设为异步方法。

    所以,类似:

    - (void)loadDataWithCompletionBlock:(void (^)(NSMutableArray *data))completionBlock {
    
        NSString *url = @"http://localhost/xampp/flashbackapi/";
    
        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
    
            [data addObject:responseObject];
            completionBlock(data);
    
    
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error %@",error);
            // TODO: Return completionBlock with empty array (or error?)
        }];
    };
    

    这样调用:

    ClubsTableViewController __weak *weakSelf = self; 
    [self loadDataWithCompletionBlock:^(NSMutableArray *data) {
        weakSelf.teams = data;
    }];
    

    此外,您似乎没有将 NSMutableArray 用作数组,因为它似乎总是只包含一个元素。

    【讨论】:

    • 非常感谢,我是初学者(如您所见,哈哈),所以对我来说有些奇怪。
    • 没问题。刚刚添加了 weakSelf 以确保不会发生保留循环。
    • 我在 TableViewController 的 ViewDidLoad 中调用了 [self loadDataWithCompletionBlock] 方法,所以我想我不需要持有 ClubsTableViewController 的引用。其实我还有一个问题,这是正确的做法吗?因为我总是学会将控制器和视图的数据分开保存。但是当我在 ClubsTableViewController 中实现 loadDataWithCompletionBlock 时,我不需要回调,但这是正确的做法吗?
    • 附注:在调用之前始终检查是否设置了块: if (completionBlock) { completionBlock(data); }
    • @Navid 这类问题的答案总是“视情况而定”。但是,如果您只想从云中检索一些简单的数据,将其存储在数组/字典中并将其显示给用户,那么我就不会为单独的类(即模型层)而烦恼。对于更复杂的数据管理(例如检索、存储和显示嵌套 JSON),您可能需要创建一些类来帮助管理您的数据。
    【解决方案2】:

    AFNetworking GET 方法异步获取数据。在您的 loadData 方法中,您只启动网络调用,当网络请求完成时,响应设置为数组属性。您的 loadData 方法在此之前返回,因此数组仍然是空的。

    您应该将一个块作为参数传递给 loadData 方法,并在 AFNetworking 完成网络请求后调用此块。

    【讨论】:

    • 我知道异步是这个问题的主要问题,但我没有得到的是在成功回调之后我将响应对象添加到我的数组中返回这个数组 soo 在源的哪个部分我迟到?我不想要一个简单的源解决方​​案,但如果有人能给我一个提示,我会很感激的。
    • @gavdotnet 更快 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多