使用故事板,您无法轻松访问 appDelegate 中的第一个视图控制器(尽管一旦您这样做了prepareForSegue
可以轻松地将 ManagedObjectContext 传递到导航堆栈中。
我决定为每个需要核心数据访问的视图控制器(或每个视图控制器的超类)提供一个 moc 成员:
@synthesize moc = _moc;
@property (nonatomic) __weak NSManagedObjectContext *moc;
我对此感到不安,因为这似乎不是一种非常优雅的方法——代码太多。但直接分配需要在 viewControllers 数组中指定绝对索引,并在每次 ManagedObjectContexts 的要求发生变化时更改 appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
// rootView gets a tab bar controller
for(UINavigationController *navController in tabBarController.viewControllers) {
for(UIViewController *viewController in navController.viewControllers) {
if([viewController respondsToSelector:@selector(setMoc:)]) {
[viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext];
NSLog(@"Passed moc to %@", [viewController description]);
}
}
}
return YES;
}
这种方法有哪些缺陷以及是否有更好的方法?尝试更通用是否更好:
- (void)assignManagedObjectContextIfResponds:(UIViewController *)viewController {
if([viewController respondsToSelector:@selector(setMoc:)]) {
[viewController performSelector:@selector(setMoc:) withObject:self.managedObjectContext];
NSLog(@"Passed moc to %@", [viewController description]);
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSMutableArray *viewControllers = [NSMutableArray array];
UIViewController *firstLevelViewController = self.window.rootViewController;
if([firstLevelViewController respondsToSelector:@selector(viewControllers)]) {
NSArray *firstLevelViewControllers = [firstLevelViewController performSelector:@selector(viewControllers)];
for(UIViewController *secondLevelViewController in firstLevelViewControllers) {
if([secondLevelViewController respondsToSelector:@selector(viewControllers)]) {
NSArray *secondLevelViewControllers = [secondLevelViewController performSelector:@selector(viewControllers)];
for(UIViewController *thirdLevelViewController in secondLevelViewControllers) {
[viewControllers addObject:thirdLevelViewController];
}
} else {
[viewControllers addObject:secondLevelViewController];
}
}
} else {
// this is the simple case, just one view controller as root
[viewControllers addObject:firstLevelViewController];
}
// iterate over all the collected top-level view controllers and assign moc to them if they respond
for(UIViewController *viewController in viewControllers) {
[self assignManagedObjectContextIfResponds:viewController];
}
return YES;
}
不知道我是否理解正确,但为什么不直接将托管对象上下文留在 AppDelegate 类中,并将所有实例化逻辑留在那里。从那时起您就可以提出要求。
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
然后你就可以随时随地回忆起来。
NSManagedObjectContext *moc = [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
为了方便起见,我为其声明了一个定义:
#define MOC [(YourApplicationDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]
因此这变成:
[MOC save:&error];
你可以把它带到任何你喜欢的地方。
只需尝试查看 Xcode 中 CoreData 应用程序自动生成的代码,您就会发现其中有许多带有 CoreData 的访问器,并且 CoreData 本身在第一次请求时会延迟初始化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)