Eri*_*erg 21 cocoa-touch core-data objective-c
所以在我看来这里有一个Catch-22的情况.请注意以下广泛(且巧妙)持有的应用程序架构的立场:
你是如何解决这个问题的?当视图控制器从nib中唤醒时,是否使用NotificationCenter发布通知,然后在上下文引用中传递app delegate?这是我能想到的第一种方式,只有#1和#2,但这对我来说也是一种扭曲.
有更优雅的方式吗?
编辑:初始化视图控制器时进行通知可能是一种竞争条件,因为如果您正在使用Storyboard,您的tabbar的子视图控制器往往在启动时被初始化(尽管sans-view加载).所以你必须在viewDidLoad中做这样的通知,这对于MVC约定来说是一个坏主意.在用户执行与视图相关的任何操作之前,它还会将您的任务与数据模型(例如预缓存性能)相关联.
Dan*_*ert 13
将NSManagedObject实例传递给视图控制器时,该视图控制器可以保留这些对象.然后,它可以通过调用通过这些托管对象访问NSManagedObjectContext
-[NSManagedObject managedObjectContext]
Run Code Online (Sandbox Code Playgroud)
我不确定这是否适用于您的特定情况,但通常会这样.应用程序委托或根视图控制器创建上下文,然后传递托管对象.
如果你需要在多个地方使用上下文,我发现另一种模式是有用的:
子类NSManagedObjectContext:
@interface MyManagedObjectContext : NSManagedObjectContext
+ (MyManagedObjectContext *)mainThreadContext;
@end
Run Code Online (Sandbox Code Playgroud)
即UI /主线程的单例上下文.这比使用App委托更干净,因为其他类不必访问App委托,但可以直接使用此类.此外,商店和模型的初始化可以封装到这个类中:
@implementation MyManagedObjectContext
+ (MyManagedObjectContext *)mainThreadContext;
{
static MyManagedObjectContext *moc;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
moc = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
// Setup persistent store coordinator here
});
return moc;
}
@end
Run Code Online (Sandbox Code Playgroud)
我发现自你发布问题以来已经过了一段时间,但我有一个不同的方法,我想与你和其他人分享.
我假设您要在所有/部分视图控制器中注入托管对象上下文,这些视图控制器显示为UITabViewController的选项卡,并且您正在使用带有UITabBarController的Storyboard作为rootViewController.
在AppDelegate标头中,让AppDelegate实现UITabBarControllerDelegate协议.
@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
...Run Code Online (Sandbox Code Playgroud)在AppDelegate实现中添加以下UITabBarControllerDelegate方法.它将负责在具有该属性的任何视图控制器中设置托管对象上下文.
- (BOOL) tabBarController:(UITabBarController *)tabBarController
shouldSelectViewController:(UIViewController *)viewController {
if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) {
if ([viewController performSelector:@selector(managedObjectContext)] == nil) {
[viewController performSelector:@selector(setManagedObjectContext:) withObject:self.managedObjectContext];
}
}
return YES;
}Run Code Online (Sandbox Code Playgroud)在您的应用程序中:didFinishLaunchingWithOptions:将self设置为UITabBarController委托.
UITabBarController *tabBarController = (UITabBarController *) self.window.rootViewController;
tabBarController.delegate = self;Run Code Online (Sandbox Code Playgroud)遗憾的是,第一个要加载的视图控制器在那时(in tabBarController.selectedViewController)尚未就绪,并且也不会调用该委托.因此,设置第一个的最简单方法是观察TabBarController的selectedViewController属性
[tabBarController addObserver:self forKeyPath:@"selectedViewController"
options:NSKeyValueChangeSetting context:nil];Run Code Online (Sandbox Code Playgroud)
并把它放在那里.
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
[object removeObserver:self forKeyPath:@"selectedViewController"];
UIViewController *viewController = [change valueForKey:NSKeyValueChangeNewKey];
if ([viewController respondsToSelector:@selector(setManagedObjectContext:)]) {
if ([viewController performSelector:@selector(managedObjectContext)] == nil) {
[viewController performSelector:@selector(setManagedObjectContext:) withObject:self.managedObjectContext];
}
}
}Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
4492 次 |
| 最近记录: |