2011-08-07 273 views
2

在我的AppDelegate中,我从互联网上下载了一些数据并将其存储到一个数组中。我想我的一个ViewController访问该数组。我怎么会这样做呢?这是一个很好的情况来实现委托或协议?如果是这样,有人可以推荐一个很好的教程吗?在类之间传递对象

谢谢

编辑:

请注意在每次发射的数据刷新,所以没有必要核心数据或Plist档案。此外,数据是我创建的自定义对象,因此它们不能存储在plist中。

+0

我认为,答案取决于如果数据是不可变的,只装载一次在启动时(推到视图 - 控制ONCE),或者如果数据是可变的,有兴趣的视图需要通知的变化(可观测PUSH ),或者视图控制器需要从数据对象中按需提取数据。 – JAL

+0

它真的很复杂,我认为我们可以阅读很多用户试图实现的内容以及他正试图解决的问题,我只是读取这些内容,因为他试图访问他存储在其应用程序代理中的数据。是的,设计选择是有问题的,但纯粹基于所提出的问题,其相当简单。 “我如何从应用程序的任何位置访问存储在我的应用程序代理中的数据” – Matt

回答

3

你有2种选择:

  1. 实现一个委托协议
  2. 使用NSNotifications

每个的优缺点都很好地列出在这个问题和答案中: Delegates v Notifications

由于通知是更容易实施,而且可能已经足够满足您的需求,您可以通过以下步骤实现:

  1. 在课堂上,你下载的数据: 当数据被下载和阵列填充,包括下面的行:

NSDictionary *dict = [NSDictionary dictionaryWithObject:array forKey:@"Data"]; [[NSNotificationCenter defaultCenter] postNotificationName:@"DataDownloaded" object:self userInfo:dict];

  • 在类要在其中接收数据:
  • 2.1以下行添加到您的viewDidLoad方法:

    `[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataDownloaded:) name:@"DataDownloaded" object:nil]; 
    

    2.2创建dataDownloaded选择:

    • (无效)dataDownloaded:(NSNotification *)注意{

      NSDictionary *dict = note.userInfo; NSArray *dataArray = [note.userInfo objectForKey:@"DataDownloaded"];

    2.3添加以下行的dealloc和viewDidUnload:

    [[[NSNotificationCenter defaultCenter] removeObserver:self]; 
    
    +0

    我不认为这真的回答了这个问题,但OP并没有表明他知道数据何时有问题,但是如何从他的应用中的其他地方访问它。我个人发现通知有点粗糙,但倾向于适合应用程序的非功能部分,例如可达性。一些更好的代码设计可能会将数据封装在通过工厂接口(保持可测试性)可用的专用类中作为伪单元。 – Matt

    0

    您可以将数据存储在plist文件中并将其用于所有视图控制器。这样,您不必担心数据的大小(因为您将按需加载并立即释放它)。在你的其他观点

    你必须写:如果你想然后保存您的委托数组中,你必须创建委托的参考任何视图,您可以在这样的视图访问阵列

    +0

    问题是我的数据不是Foundation的一部分。这是我创建的一个自定义对象,哪个plists不能存储。此外,我不需要使用核心数据作为数据在每次启动时刷新。 – darksky

    +0

    你可以存储在plist文件或'档案'中,而不使用/不知道coredata。你所需要做的就是使数据符合NSCoding协议。如果这是不可能的,我怀疑是否有任何优雅的方式,比维护全球数据和处理同步。 – Tatvamasi

    1

    在.h文件中

    #import "YourDelegateFile.h",并声明varialble

    YourDelegateFile *appDelegate ; 
    

    在.m文件:

    - (void) viewDidLoad 
    { 
        appDelegate = (YourDelegateFile *)[UIApplication sharedApplication] delegate]; 
    
        NSArray *aArray = [appDelegate yourArrayName]; //yourArrayName is an array that you have declare in delegate 
    } 
    

    希望它可以帮助你。

    +0

    虽然这被认为是好设计吗?我已经多次听说它根本不被推荐... – darksky

    +0

    它虽然回答了原来的海报问题,但这个代码可能无法工作,具体取决于选择器“yourArrayName”是什么 – Matt

    0

    您只需访问存储在appdelegate中的数据。我不认为这是问题的最佳解决方案,但为了做的事情,你想要的方式。

    所以你申报财产在你的appdelegate .h文件中

    NSMutableArray* myArray_; 
    

    然后在.m文件属性添加到同一个文件

    @property (nonatomic, retain) NSMutableArray* myArray; 
    

    确保您的合成物业

    @synthesize myArray = myArray_; 
    

    某处你的appdelegate .m文件,你会设置的值

    然后,在你的代码的其他地方,你可以访问属性中的appdelegate像这样

    MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate 
    NSMutableArray* localArray = appDelegate.myArray; 
    

    注意,良好的封装应该要使用一个NSArray但我用可变保持代码的短。

    此外,使用的appdelegate作为节目数据的全局存储是不是一个好主意,它打破了很多的规则,你不应该打破,单一职责原则是一个好的开始。理论上,应该是在一个专用的存储类应用程序数据,也许是单身或更好的可测试性由一个工厂类服务的一个实例类。这样,你的数据是从已知的良好定义的实体访问,它是可测试的,它表彰优秀的设计原则

    +0

    在我的情况下,你会只是推荐单身课程?基本上我有一个10个频道的名单。对于每个频道,我需要存储三件事情:现在,接下来和以后。那么像单个类中的两个嵌入式NSDictionaries就可以做到这一点?请注意我也在谈论优秀的设计。良好的设计对我来说与功能一样重要。 – darksky

    +0

    单身人士是有争议的看到这篇文章http://www.ibm.com/developerworks/webservices/library/co-single/index.html他们确实有自己的位置,但他们打破了很多良好的做法,如单一责任原则,他们负责提供给您的应用程序的功能以及管理只有一个实例的事实,他们也使测试变得困难。有一些更精细的方法可以更好地利用工厂来管理单件事情。一本完整的书可以专注于这个主题,身份证建议阅读有关它.. – Matt

    +0

    个人,它听起来像是唯一的区别现在,接下来是你看这些数据的时间,虽然这使得假设你如何请求数据以及它如何返回。为什么不把频道建模成它负责了解它的节目的对象,然后有一些操作来确定哪一个是现在,将来或稍后,你可能需要一个包含频道对象的channelManager类,你也可能发现它有助于将请求作为一个对象进行建模,并围绕该请求建立一些代码,以便发出请求并处理响应由你决定 – Matt

    0

    您可以发送通知,如果应用程序委托了新的数据和所有相关的控制器都知道,他们需要更新的观点。为此,您可以使用NSNotificationCenter。例如

    - (void)newDataLoaded { 
        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:arrayOfData forKey:@"data"]; 
        [[NSNotificationCenter defaultCenter] postNotificationName:@"data updated notification name" object:nil userInfo:userInfo]; 
    } 
    

    如果某些控制器感兴趣的数据更新它应该尽快认购该通知越好:

    - (void)viewDidLoad { 
        ... 
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataUpdatedNotificationHandler:) name:@"data updated notification name" object:nil]; 
        ... 
    } 
    

    不要忘记从通知退订,如果你不需要它。在viewDidUnloaddealloc方法中使用[[NSNotificationCenter defautCenter] removeObserver:self]

    - (void)dataUpdatedNotificationHandler:(NSNotification*)notification { 
        NSArray *data = [[notification userInfo] objectForKey:@"data"]; 
        // update your view here 
    }