iOS:如何在显示前预加载数据

Posted

技术标签:

【中文标题】iOS:如何在显示前预加载数据【英文标题】:iOS: How to Preload Data before Display 【发布时间】:2012-11-09 12:01:43 【问题描述】:

在我正在制作的IPhone 应用程序中,我有一个initialViewController

(1) 带有按钮。单击按钮后,它会转到另一个视图控制器

(2),此时从 CoreData 文件加载数据并将其显示给用户。

我的问题是 (2) 的加载和数据的实际显示之间有一个小的延迟。这当然是因为加载数据需要一点时间。我正在这样做asynchronously,我的目标是永远不显示旋转轮或加载屏幕(更用户友好)。

我想要做的是“preload”(1) 处的数据,而不是 (2) 处的数据,这样数据应该在 (2) 加载时已经加载并且应该立即显示。 我知道如何在 (1) 处加载数据,但我不知道如何轻松地将其传递给 (2)。我不能用 segue 来做,因为我的应用实际上比上面描述的要复杂一些,而且通过 segue 做起来很麻烦。

我听说可以使用“AppDelegate”,但由于我是编程新手,我不知道如何有效地使用它。我一直在关注的在线课程并没有对如何使用它提供非常清晰的见解,所以我有点迷茫。

【问题讨论】:

我不认为显示加载屏幕或旋转轮对用户不友好。有时应用程序需要时间来做某事。最好表明您很忙,以便用户知道后台正在发生某些事情,而不是让他们等待并盯着无响应的屏幕。 我同意。我打算有一个纺车以防万一,但我只是想尽可能减少用户感知的加载时间。 【参考方案1】:

看到你对帕拉斯帖子的评论后,我有一个更好的解决方案给你:

创建一个名为fileLoader的NSObject子类

//in fileLoader.h
@interface fileLoader : NSObject 

+(fileLoader *)sharedInstance;
+(void)createSharedInstance;
//add functions and variables to load, store data for use in another class
@end

那么,

//in fileLoader.m
@implementation fileLoader
static id _instance;


+(void)createSharedInstance
    _instance = [[fileManager alloc] init];

+(fileManager *)sharedInstance
    return _instance;

//other functions for storing, retrieving, loading, standard init function, etc.

@结束 现在您可以调用[fileManager createSharedInstance] 来实例化一个文件管理器,您可以通过调用[fileManager sharedInstance] 上的函数在任何地方使用它。

【讨论】:

我在我的游戏中也使用了类似的东西,我有一个音频管理器类,我与之共享一个实例,这样我就可以保留常用声音的缓存,还有其他好处。【参考方案2】:

您可以使用某种 DataManager 对象,在加载数据后将数据存储在其中,以便在应用程序的任何位置轻松检索。如果您只需要在应用启动时加载一次即可。

诀窍是让它成为一个单例对象,因此无论您在应用程序中的哪个位置引用它,它都将是已经预加载数据的同一个实例。我在我的项目中经常使用这些来管理我在应用程序中需要的所有数据。

例子不胜枚举

【讨论】:

这似乎正是我正在寻找的(虽然 WolfLink 的答案非常有用,只是不够灵活,我认为这可能会在以后更有用)。感谢您指出单例的使用,我不知道它们。【参考方案3】:

AppDelegate 更适合将数据从 (2) 传递到 (1)。要将数据从 (1) 加载到 (2),您可以使用与 (2) 加载相同的函数,因为 (1) 将 (2) 视为 viewController 的实例。就是这样:

//In OneViewController.m
-(void)viewDidLoad:(BOOL)animated
    [super viewDidLoad:animated];

    TwoViewController *VCTwo = [[TwoViewController alloc] initWithNibName:@"TwoViewController" bundle:nil];
    //note that I am only instantiating VCTwo, I am not displaying it.


-(void)loadVCTwoFromVCOne
    [TwoViewController preloadInformation];
    //simply call the function to load the data on the instance of the viewController before displaying it


-(IBAction)presentVCTwo
    [self presentViewController:VCTwo animated:YES completion:nil];
    //when you are ready, you can display at any time

【讨论】:

所以这意味着我可以在加载之前“实例化”我的 (2),然后再实际加载它?好吧,我不知道我能做到这一点。我认为这应该很好用,谢谢。 是的,事实上我在我的一个应用程序中做了类似的事情。这是一个游戏,为了加载关卡,我将关卡名称传递给游戏引擎,以便在显示之前进行准备。 知道这一点真的很有用;我遇到了很多问题,因为我找不到从控制器轻松传递数据的方法……我以后会记住的。谢谢:)。【参考方案4】:

属性将NSMutableArray 与您这样的数据合成在yourNextViewController.h 文件中

@property(nonatomic, retain) NSMutableArray *nextViewArray;

yourNextViewController.m 文件中只需像下面这样合成..

@synthesize nextViewArray;

然后像下面这样昏倒..

      yourNextViewController *objNextView = [[yourNextViewController alloc]initWithNibName:@"yourNextViewController" bundle:nil];
      objNextView.nextViewArray = [[NSMutableArray alloc]init];
      objNextView.nextViewArray = yourDataArray;
      [objNextView.nextViewArray retain];
      [self.navigationController pushViewController:objNextView animated:YES];
      [objNextView release];

你也可以传递字符串或字典而不是数组..

【讨论】:

您好,感谢您的回答。如果我理解正确,您将在 segue 发生时传递数据。正如我所说,不幸的是,在我的情况下并不那么容易,因为我不只使用一个 segue,而是几个,而且通常很混乱(我试过这样做,结果真的很乱,我没有得到我想要的是)。因此,我正在寻找一种无需通过 segue 传递数据的方法。无论我在哪个视图控制器中,我都可以从中获取数据。 @Konrad ,此代码对于将数据从一个视图传递到另一个视图很有用,因此在这里您只需一次从网络下载数据并在全球范围内使用它。但它可以很好地解决您的问题。 . :) WolfLink 的回答帮助我澄清了您自己的回复,并且我更好地理解了您想说的话。感谢您的帮助。

以上是关于iOS:如何在显示前预加载数据的主要内容,如果未能解决你的问题,请参考以下文章

vue加载组件报错说提前加载

yii select2 插件预加载数据

预加载与智能预加载(iOS)

选择 searchBar 时在 UISearchController 中预加载数据

类加载应用程序上下文 Spring

如何使用 Restkit 和 Core Data 存储对象和种子预加载数据