Ios 使用单个数据源的多个UIView

Ios 使用单个数据源的多个UIView,ios,objective-c,uiview,Ios,Objective C,Uiview,如何创建多个视图可以访问的数据源 我当前的项目有一个TabBarController链接到多个视图,所有视图都需要访问同一个好友列表 目前,我将数据源存储在一个名为DataHolder的单例类中,下面显示了该类的代码 DataHolder.m #import "DataHolder.h" @interface DataHolder(){ DataQuery *dataQuery; NSMutableArray *friendList; } @end @implementation

如何创建多个视图可以访问的数据源

我当前的项目有一个
TabBarController
链接到多个视图,所有视图都需要访问同一个好友列表

目前,我将数据源存储在一个名为
DataHolder
的单例类中,下面显示了该类的代码

DataHolder.m

#import "DataHolder.h"
@interface DataHolder(){
    DataQuery *dataQuery;
    NSMutableArray *friendList;
}
@end
@implementation DataHolder
+(DataHolder*)sharedInstance{
    static DataHolder *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[DataHolder alloc]init];
    });
    return _sharedInstance;
}

-(id)init{
    self = [super init];
    if (self){
        NSLog(@"DataHolder init method called");
             dataQuery =[[DataQuery alloc]init];

    }
    return self;
}

-(NSMutableArray *)getFriendList{
    NSLog(@"Friend List from DataHolder %@", [dataQuery getFriendList]);
    return [dataQuery getFriendList];
}

-(void)logout{
    [friendList removeAllObjects];
}

@end
我遇到的问题是,一次不能有多个视图来保存数据。我目前正在每个viewController中使用一个
NSMutableArray
属性,并让它们调用
self.Array=[NSMutableArray ArrayWithArray:[DataHolder SharedInstance]GetFriendList]]这并不总是返回任何数据,特别是如果以前调用过另一个viewController。我还感到困惑的是,当另一个viewController拥有数据时,一些viewController不会显示数据,而下次我运行应用程序时,另一个viewController拥有数据

编辑:这里是执行查询的
dataQuery
类,而
DataHolder
保留该类

DataQuery.m

@interface DataQuery(){

    NSMutableArray *friendsToAccept;
    //NSMutableArray *friendsList;
    int *count;
}

@end
@implementation DataQuery

-(id)init{
    self = [super init];
    if (self){
        self.friendsList = [NSMutableArray new];
        //[self.friendsList mutableArrayValueForKey:@"friendsArray"];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getFriendList) name:@"friendList" object:nil];
        self.currentUser = [[CurrentUser sharedInstance]getCurrentUser];

        [self friendListQueryWithDataSource:self.friendsList];
        //[self checkForFriends];

    }
    return self;
}
-(NSMutableArray *)getFriendList{
    return self.friendsList;
}

-(void)friendListQueryWithDataSource:(NSMutableArray*)datasource{
    PFRelation *friendRelation = [self.currentUser relationForKey:@"friendRelation"];
    PFQuery *acceptedQuery = [friendRelation query];
    acceptedQuery.cachePolicy = kPFCachePolicyCacheThenNetwork;


        [acceptedQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error){
                NSLog(@"ERROR: %@ %@", error, [error userInfo]);
            }else{
                self.friendsList = [NSMutableArray arrayWithArray:objects];
                NSLog(@"Friend List from DataQuery %@", self.friendsList);
            }
        }];


}
下面是如何设置视图控制器以显示数据

#import "ConnectionTableViewController.h"


@interface ConnectionTableViewController (){
    DataHolder  *dataHolder;
}

@end

@implementation ConnectionTableViewController

- (void)viewDidLoad
{
    self.pending = [NSArray new];
    NSLog(@"%@", self.pending);
    self.friendList = [NSMutableArray new];
    self.edgesForExtendedLayout = UIRectEdgeNone;
    backgroundQueue = dispatch_queue_create("word", NULL);
    self.friendList = [NSMutableArray arrayWithArray:[[DataHolder sharedInstance] getFriendList]];


      [super viewDidLoad];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"friendList"]) {
        for (PFUser *user in [[DataHolder sharedInstance]getFriendList]){
            [self.friendList addObject:user];
        }
        [self.tableView reloadData];
    }

}

findobjectsinbackgroundithblock:
是一个异步方法!在friendList完成之前,您将不会在friendList中有任何数据

尝试使
getFriendList
异步

- (void)getFriendListWithCallback:(CallbackBlock)callback {
    //...
    if (self.friendsList.count == 0) {
        [acceptedQuary findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error){
                self.friendsList = @[];
                NSLog(@"ERROR: %@ %@", error, [error userInfo]);

            } else {
                self.friendsList = [NSMutableArray arrayWithArray:objects];
                NSLog(@"Friend List from DataQuary %@", self.friendsList);
            }
            if (callback) callback(self.friendsList);
        }];
    } else {
        if (callback) callback(self.friendsList);
    }
}

使用NSNotificationCenter在数据下载完成后获得通知。在我看来,您正在使用Parse作为后端

getFriendList
是异步的吗?不,getFriendList在来自DataHolder的代码中没有使用异步进程,ViewController也没有获得异步实例。总的来说,我不认为它们是异步的,它们是同步的。请尝试将
\u sharedInstance
的声明移出该方法。将它移到其他ivar。实际上不起作用,在设置sharedInstance时会给我带来很多错误。我不是有意将其设置为ivar。这是一个静态变量。这就是为什么我在每个viewController中放置-(void)observeValueForKeyPath:(NSString*)对象的键路径:(id)对象更改:(NSDictionary*)更改上下文:(void*)上下文以重新加载tableView数据的原因。然而,这并不能解决显示问题。我想知道是否有更好的观察方法来重新加载tableView数据。解决方案是使您的
getFriendList
方法在dataHolder类中异步。getFriendList?异步如何解决这个问题?您正在尝试以同步方式使用异步。您正在使用的解决方案是KVO,它非常糟糕。使用回调块。