我的应用有两个由标签栏控制器管理的视图。其中一个视图是Google Map(使用他们的SDK的GMSMapView),另一个是显示相同数据列表的TableView。地图上的标记与TableView中的数据相同(只是相同数据的替代显示)。
我从NSURLSessionDataTask获取数据。我想知道在两个视图之间共享数据的最佳方式是什么。显然,我不想为每个视图获取两次数据。但我不确定在两个视图之间使共享数据可用/同步的最佳做法是什么。
提出了类似的问题,但没有回答here。
答案 0 :(得分:2)
您可以创建一个模型类,它将数据/字典/自定义类对象中的地图相关数据保存在一起。您可以将此模型类设置为单例(只能初始化一次)。两个视图控制器(即地图和表视图)都可以引用此模型来立即在不同视图中填充日期。
Model Class
-----------
@property (strong, nonatomic) MyCustomDataRepresentationObj *data;
+ (id)sharedModel {
static MyModelClass *sharedModel = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedModel = [[self alloc] init];
});
return sharedModel;
}
-(void)fetchMapDataWithCompletionBlock:(void(^)(id response, NSError *error)onComplete
{
// Check if data is available.
// Note: You can add a refresh data method which will fetch data from remote servers again.
if (!data) {
__weak MyModelClass *weakSelf = self;
// Make HTTP calls here, assume obj is returned value.
// Convert network response to your data structure
MyCustomDataRepresentationObj *objData = [MyCustomDataRepresentationObj alloc] initWith:obj];
// Now hold on to that obj in a property
weakSelf.data = objData;
// Return back the data
onComplete(objData, error);
} else {
onComplete(objData, nil); // Return pre fetched data;
}
}
现在在视图控制器中,您必须调用模型类方法,该方法将进行网络调用(如果需要)并在完成块中返回数据。
View Controller 1
-----------------
-(void)viewDidLoad
{
// This is where the trick is, it returns the same object everytime.
// Hence your data is temporarily saved while your app is running.
// Another trick is that this can be accessed from other places too !
// Like in next view controller.
MyModel *myModelObj = [MyModel sharedModel];
// You can call where ever data is needed.
[myModelObj fetchMapDataWithCompletionBlock:^(id response, NSError *error){
if (!error) {
// No Error ! do whats needed to populate view
}
}];
}
在其他视图控制器中执行相同操作。
View Controller 2
-----------------
-(void)viewDidLoad
{
// Gets the same instance which was used by previous view controller.
// Hence gets the same data.
MyModel *myModelObj = [MyModel sharedModel];
// Call where ever data is needed.
[myModelObj fetchMapDataWithCompletionBlock:^(id response, NSError *error){
if (!error) {
// No Error ! do whats needed to populate view
}
}];
}
注意:我刚刚在这里记下了这些代码行,可能存在语法错误。它只是为了得到基本的想法。
答案 1 :(得分:1)
UITabBarController充当容器。
因此,从您的2个子ViewControllers,您可以使用属性parentViewController
访问TabBarViewController。
因此,如果您想与2个子ViewControllers共享相同的数据,则可以在UITabBarController中获取和存储数据。而且,从你的UIViewControllers,你可以像这样访问它
MyCustomTabBarController *tabBar = (MyCustomTabBarController*)self.parentViewController;
id data = tabBar.myCustomData;
答案 2 :(得分:0)
使用单例模式创建单例类并在AppDelegate.m
中初始化单例实例,这样您就可以使用
答案 3 :(得分:0)
数据提取对象怎么样?创建一个新的类,它会对您的数据位进行请求并在内部存储结果。
然后,您可以使用多种不同的方法将数据导入ViewController:
直接引用在Tab键控制器上设置viewControllers属性之前,将此对象与ViewControllers上的每个ViewController相关联。
这个新类的接口可能包括一组获取的结果,以及一个方法(当请求完成时带回调),告诉对象获取更多结果。
通知中心您的对象可以在有更多数据时发布通知,并且只包含一种方法来开始请求更多数据。
委托+注册您可以为想要了解数据集更改的对象创建协议,确保所有必需的ViewControllers符合要求,并在数据上具有委托NSArray属性获取对象。这比Notification Center更加手动,但如果您需要一个非常强大的界面,它会稍微容易一些。
毋庸置疑,有很多方法可以解决这个问题,但它们都是从指定一个类开始执行获取/存储数据的特定任务开始的。