使用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,那么它可能不属于那里!