将AppDelegate导入模型?

我试图统一模型文件中特定类的所有功能。 例如,我会在模型'Contact.h / Contact.m'中有一个函数fetchContactWithName:(NSString *)名称,我的viewcontroller随后会调用它。

在这种情况下,将AppDelegate.h文件导入模型文件是否是一个坏主意,因为我需要访问其managedObjectContext?

#import "AppDelegate.h"

@implementation Contact

...

+ (Contact *) fetchContactWithName:(NSString *) name {
  AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Contact" inManagedObjectContext:delegate.managedObjectContext];
  [fetchRequest setEntity:entity];

  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", name];
  [fetchRequest setPredicate:predicate];

  NSError *error = nil;
  NSArray *fetchedObjects = [delegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];

  Contact *fetchedContact;
  for(Contact *contact in fetchedObjects) {
      fetchedContact = contact;
  }

  if(fetchedContact != nil) {
      return fetchedContact;
  } else {
      return nil;
  }

}
@end

在我看来,直接请求不同的类来获取您的托管对象上下文是一个糟糕的主意。 因为

  • 你不能真正在不同的项目中重用你的类(想想OS X应用程序)
  • 您无法在不同的上下文中获取联系人(请考虑后台导入)
  • 如果方法询问其他课程,则不能使用单元测试
  • 你应该告诉这个方法应该在哪个上下文中获取。
    而不是+ (Contact *) fetchContactWithName:(NSString *) name您的方法签名应该看起来像这样:

    + (Contact *)fetchContactWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
    

    每个viewController应该有一个对应用程序委托中使用的NSManagedObjectContext的引用。 您可以将上下文的引用传递给application:didFinishLaunchingWithOptions:每个viewController application:didFinishLaunchingWithOptions: :,并且每次您推送或呈现新的viewController时,都会将该上下文实例传递给它。

    这可能看起来像很多工作,但有一天你会从“告诉,不要问”的方法中受益。


    我认为,这是个坏主意 。 因为它是OOP丑陋的。 我建议什么? 你应该像这样做一个单例类SharedStorage

    + (SharedStorage*)sharedStorage
    {
        static SharedStorage* _sharedStorage = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _sharedStorage = [[self alloc] init];
        });
        return _sharedStorage;
    }
    
    - (SharedStorage*)init {
        self = [super init];
        if (self)
        {
            [self setupPersistentStoreCoordinator];
        }
        return self;
    }
    
    - (NSManagedObjectModel*)__managedObjectModel
    {
        if (_managedObjectModel_ == nil)
        {
            NSBundle *mainBundle = [NSBundle mainBundle];
            NSURL *modelURL = [mainBundle URLForResource:@"yourURL" withExtension:@"momd"];
            _managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        }
        return _managedObjectModel_;
    }
    
    
    - (void)setupPersistentStoreCoordinator
    {
        if (_storeCoordinator != nil)
            return;
        NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"YourDB.sqlite"];
        NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
        NSError *error;
        _storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self __managedObjectModel]];
        if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        }
    }
    

    在你想使用上下文的地方,你必须用同样的persistentStoreCoordinator创建一个新的NSManagedObjectContext

    self.context = [NSManagedObjectContext new];
        self.context.persistentStoreCoordinator = [[SharedStorage sharedStorage] storeCoordinator];
    

    要访问AppDelegate类的东西,你需要

    在头文件中

    extern AppDelegate *appDelegate; 
    

    和AppDelegate.m文件中

    AppDelegate *appDelegate = nil;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
    }
    

    现在在模型视图控制器中导入AppDelegate文件,您可以通过其对象访问其方法。

    链接地址: http://www.djcxy.com/p/91647.html

    上一篇: Import AppDelegate into models?

    下一篇: UICollectionView not displaying cells after fast scroll