如何将数据库从 AppDelegate 传递到 ViewController

Posted

技术标签:

【中文标题】如何将数据库从 AppDelegate 传递到 ViewController【英文标题】:How to pass database from AppDelegate to ViewController 【发布时间】:2015-03-02 19:24:22 【问题描述】:

我不知道为什么这个代码错误。 请帮忙。 我读了一些文章,我认为问题在于上下文。 我该怎么办?

这个程序是关于将 coredata 中的数据显示到 viewcontroller 中的标签。

AppDelegate.h    
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

AppDelegate.m
#import "AppDelegate.h"
#import "Test.h"
#import "ViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
// Override point for customization after application launch.

NSManagedObjectContext *context = [self managedObjectContext];
Test *t = [NSEntityDescription insertNewObjectForEntityForName:@"Test"
                                        inManagedObjectContext:context];
t.name = @"please";



return YES;

ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic,strong) NSArray *temp;
@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
@end

ViewController.m
#import "ViewController.h"
#import "Test.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize managedObjectContext;
@synthesize temp;
- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription
                                    entityForName:@"Test"  
                       inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    NSError *error;
self.temp = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
for(Test *info in temp)

    _label.text = info.name;




- (void)didReceiveMemoryWarning 
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.


@end

Test.h    
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>


@interface Test : NSManagedObject

@property (nonatomic, retain) NSString * name;

@end

Test.m
#import "Test.h"


@implementation Test

@dynamic name;  
@end

我不知道为什么这个代码错误。 请帮忙。 我读了一些文章,我认为问题在于上下文。 我该怎么办?

【问题讨论】:

能否详细说明错误发生在哪里?另外,请尝试删除所有不必要的代码(例如:didReceiveMemoryWarnimg),因为它不能帮助我们快速进入主题。 在 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:managedObjectContext] 上出错; [fetchRequest setEntity:entity]; 我认为是因为 ViewController 不知道来自 AppDelegate 的上下文。 如何将上下文表单 AppDelegate 传递给 ViewController 是重点。我认为。 你可以尝试创建一个单例来保存上下文,而不是传递上下文。这有它的缺点,但如果你没有做任何花哨的事情,它可能对你有用。 【参考方案1】:

在您的视图控制器中,替换以下行:

@synthesize managedObjectContext;

有了这个:

- (NSManagedObjectContext *) managedObjectContext 
    return ((AppDelegate *)[[UIApplication sharedApplication] delegate]).managedObjectContext;

此属性将返回您在应用程序委托中设置的对象上下文,而不是在您的视图控制器中存储另一个不同的对象上下文。

还有其他方法可以做到这一点,例如按照 Singleton 模式创建一个 Core Data 帮助器类(正如@NewYork167 建议的那样),但这至少应该可以解决您当前的问题。

【讨论】:

【参考方案2】:

对于任何将来的参考,您也可以尝试像这样子类化 NSManagedObjectContext:

@interface MyManagedObjectContext : NSManagedObjectContext

+ (MyManagedObjectContext *)mainThreadContext;

@end

@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

参考:Best practices for passing NSManagedObjectContext around to UITabBarController child view controllers?

【讨论】:

以上是关于如何将数据库从 AppDelegate 传递到 ViewController的主要内容,如果未能解决你的问题,请参考以下文章