使用AppDelegate共享数据

我发现了一些解释如何使用AppDelegate在iOS应用程序中的对象之间共享数据的资源。 我已经很轻松地实现了它,在我的情况下,这看起来是一个很好的方法。 思考使用AppDelegate可以做什么,我想知道应该在哪里画线。

显然还有其他的方式来跨视图控制器共享数据 ,使用Singleton对象和NSUserDefaults 。 什么时候使用AppDelegate共享数据是合适的? 在我目前的情况下,我使用这种方法来存储用于推送通知的appleDeviceToken。 当用户login或注销应用程序时,我使用该标记。


在MyAppDelegate.h我声明属性:

@property (nonatomic, retain) NSString *appleDeviceToken; 

在MyAppDelegate.m中我合成了AppleDeviceToken,然后设置它:

 @synthesize appleDeviceToken; ------------------------------------------------------ - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken { NSString *devToken = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString: @" " withString: @""]; appleDeviceToken = devToken; } 

然后,在我的LoginViewController.m我检索它并将其发布到我的服务器:

  NSString *urlForDeviceTokenPost = [NSString stringWithFormat: @"/api/users/%i/appleDeviceToken", userId]; MyAppDelegate *appDelegate = (MyAppDelegate*) [UIApplication sharedApplication].delegate; NSString *appleDeviceTokenStr = appDelegate.appleDeviceToken; AppleDeviceToken *appleDeviceToken = [[AppleDeviceToken alloc] init]; appleDeviceToken.deviceToken = appleDeviceTokenStr; [[RKObjectManager sharedManager] postObject:appleDeviceToken delegate:self]; 

迄今为止这个工作很好,但是这是一个理想的方法吗? 还有什么我应该知道的?

当数据和对象是真正的全局和/或不能被进一步向下的图表。 通常不需要在这个高层存储。 而且,你的实现通常对应用程序委托很less或根本不知道 – 什么比单例更糟? 上帝 – 单身:)如果应用程序委托是复杂的,出了问题。 如果应用程序委托的接口对许多实现可见(通过#import ),或者直接向其发送消息,则会出现问题。

不需要一个(惯用的ObjC)单例 – 应用程序委托有一个实例。

NSUserDefaults是为了持续小值(顾名思义) – 共享的能力是一个副作用。

由于在这种情况下数据已经被UIKit发送到应用程序委托中,所以这可能是存储数据或者对象表示的好地方。 您也可以考虑将这些消息转发给适当的处理程序。 重要的一点 – 在大多数情况下,你会希望初始化stream向对象图,并从最低点stream(例如,相对于许多对象引用回应用程序委托)。 因此,您可能会看到应用程序委托设置了顶级视图控制器的模型,但视图控制器可以设置它推送的视图控制器的模型。 通过这种方式,您将减less依赖和控制stream程,因果将更容易追踪,并且您将能够更轻松地进行testing – 不受大规模全局状况的影响。

下面的代码总是表明你做错了什么:

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

应用程序委托是UIApplication的委托。 这被称为是有原因的。 它不被称为ApplicationDataStore或甚至ApplicationCoordinator 。 事实上,你问应用程序的delegate ,然后把它作为id<UIApplicationDelegate>以外的其他东西意味着你已经要求它做的事情没有任务。 它负责pipe理UIApplication需要的东西(这并不意味着“应用程序”需要的所有东西)。

看来你已经build立了一个地方来存储这个信息: RKObjectManager 。 我会让应用程序委托传递令牌,我会有login视图控制器只是注意,是时候推它。 我甚至不会在视图控制器中放入string@"/api/users/%i/appleDeviceToken" 。 这与显示视图无关。 这是你的networking堆栈(你似乎已经安置在RKObjectManager )。 “ViewController”是指“帮助显示视图的控制器”而不是“视图所代表的操作的处理器”。

这似乎是一个适当的使用。 应用程序委托很容易被滥用,因为它是一个已经存在于每个应用程序中的易于访问的对象。 然而,它有一个真正的目的,就像它的标题所指出的那样,为应用程序对象做决定,就像表视图委托为它的表视图对象一样。

在这种情况下,您正在存储从应用程序本身传递给委托的信息。 我会说这就是画线的地方。

存储此令牌似乎与应用程序委托的目的一致,除非您有另一个专注于处理远程通知的控制器对象。 在这种情况下,你可能只是将权标传递给该控制器。

我更务实。 由于appDelegate在我的应用程序知道如何填充tabBarController和所有的导航控制器,我有几个方法,让一些任意类与其他类通信 – 通常这些是一些类(但不是单例)的单个实例。 这就是说,如果你想放在那里没有一个令人信服的理由在AppDelegate,那么它可能不属于那里!