我正在尝试统一模型文件中特定类的所有函数。例如,我在模型'Contact.h / Contact.m'中有一个函数fetchContactWithName:(NSString *)name,我的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
答案 0 :(得分:5)
在我看来,直接要求另一个类来获取托管对象上下文是个坏主意。因为
你应该告诉这个方法它应该在哪个上下文中获取
而不是+ (Contact *) fetchContactWithName:(NSString *) name
您的方法签名应该如下所示:
+ (Contact *)fetchContactWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
每个viewController都应该引用您的app delegate中使用的NSManagedObjectContext。您可以将上下文的引用传递给application:didFinishLaunchingWithOptions:
中的每个viewController,每次推送或呈现新的viewController时,都会将上下文实例传递给它。
这可能看起来像现在很多工作,但有一天你会受益于“告诉,不要问”的方法。
答案 1 :(得分:2)
我认为,这是坏主意。因为它是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]);
}
}
在您想要使用上下文的任何地方,您必须使用相同的NSManagedObjectContext
创建新的persistentStoreCoordinator
:
self.context = [NSManagedObjectContext new];
self.context.persistentStoreCoordinator = [[SharedStorage sharedStorage] storeCoordinator];
答案 2 :(得分:1)
要访问AppDelegate
课程的内容,您需要
在头文件
中extern AppDelegate *appDelegate;
并在AppDelegate.m文件中
AppDelegate *appDelegate = nil;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
}
现在在模型视图控制器中导入AppDelegate文件,您可以通过其对象访问其方法。