问题描述
我试图统一模型文件中特定类的所有函数。例如,我将在模型Contact.h / Contact.m中有一个函数fetchContactWithName:(NSString *),我的viewcontroller会调用它。
在这种情况下,将AppDelegate.h文件导入模型文件是一个坏主意,因为我需要访问其managedObjectContext?
#importAppDelegate.h
@implementation联系人
...
+(联系人*)fetchContactWithName: *)name {
AppDelegate * delegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@ContactinManagedObjectContext: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];
联系* fetchedContact;
for(Contact * contact in fetchedObjects){
fetchedContact = contact;
}
if(fetchedContact!= nil){
return fetchedContact;
} else {
return nil;
}
}
@end
在我看来,直接问一个不同的类,得到你的管理对象上下文是一个坏主意。因为
- 您不能在不同的项目中重用您的课程(例如OS X应用程式)
- 如果方法询问其他类 ,则不能使用单元测试
- You can't really reuse your classes in different projects (think OS X app)
- You can't fetch contacts in a different context (think background import)
- You can't use unit tests if the method asks other class
您应该告诉此方法应该获取的上下文。
而不是 +(Contact *)fetchContactWithName:(NSString * )name
您的方法签名应该如下所示:
+(Contact *)fetchContactWithName: *)name inManagedObjectContext:(NSManagedObjectContext *)context
每个viewController都应该引用NSManagedObjectContext你的应用程序委托。你可以在 application:didFinishLaunchingWithOptions:
中为每个viewController传递一个上下文的引用,并且每次推送或呈现一个新的viewController时,都会将上下文实例传递给它。
这可能看起来像很多工作,但有一天你会受益于告诉,不要问的方法。
I'm trying to unify all of my functions of a specific class within the model file. For instance, I would have a function fetchContactWithName:(NSString *)name in the model 'Contact.h/Contact.m', which my viewcontroller would subsequently call.
In this case, would it be a bad idea to import the AppDelegate.h file into the model file as a I need to access its 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
In my opinion it's a bad idea to directly ask a different class to get your managed object context. Because
You should tell this method in which context it should fetch.
Instead of + (Contact *) fetchContactWithName:(NSString *) name
your method signature should look like this:
+ (Contact *)fetchContactWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
each viewController should have a reference to the NSManagedObjectContext used in your app delegate. You can pass a reference of the context to each viewController in application:didFinishLaunchingWithOptions:
, and each time you push or present a new viewController you pass the context instance to it.
This might look like a lot of work now, but some day you will benefit from the "tell, don't ask" approach.
这篇关于将AppDelegate导入模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!