【问题标题】:NSManagedObjectContext: From a UIViewController, how do you get the ManagedObjectContext in iOS?NSManagedObjectContext:从一个 UIViewController,如何在 iOS 中获取 ManagedObjectContext?
【发布时间】:2011-06-28 03:46:33
【问题描述】:

您如何知道正确的 ManagedObjectContext 是什么?因为我不在 appDelegate 中(我认为代码所在的位置),并且我的应用程序不断崩溃 - 特别是在 MyTabBarViewController 的“ViewDidLoad”和 SecondViewController 的“sendPressed”方法中。

你能告诉我如何找到上下文吗?因为 alloc 初始化我自己的上下文不起作用。我想向 appDelegate 发送消息吗?我认为添加 appDelegate 头文件或调用它是错误的做法。

SecondViewController.m

#import "SecondViewController.h"

@implementation SecondViewController

- (IBAction) sendPressed:(UIButton *)sender
{
    for(UIViewController *controller in self.tabBarController.viewControllers)
    {
        if([controller isKindOfClass:[FirstViewController class]])
        {
            FirstViewController *fvc = (FirstViewController *)controller;
            [fvc realLabel];
        }
    }

    //add image to Core Data
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    Photo *photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:context];
    photo.photo = imageData;

    self.tabBarController.selectedIndex = 2;//switch over to the third view to see if it worked
}
...
@end

MyTabBarViewController.m

#import "MyTabBarViewController.h"


@implementation MyTabBarViewController
@synthesize pageControl,scroller;

-(IBAction)clickPageControl:(id)sender
{
    int page=pageControl.currentPage;
    CGRect frame=scroller.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [scroller scrollRectToVisible:frame animated:YES];
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    int page = scrollView.contentOffset.x/scrollView.frame.size.width;
    pageControl.currentPage=page;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    scroller.delegate=self;
    scroller.pagingEnabled=YES;
    scroller.directionalLockEnabled=YES;
    scroller.showsHorizontalScrollIndicator=NO;
    scroller.showsVerticalScrollIndicator=NO;
    scroller.contentSize=CGSizeMake(pageControl.numberOfPages*scroller.frame.size.width, scroller.frame.size.height);
    CGFloat scrollWidth = 0;
    int pageNumber = 0;
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    request.entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:context];
    NSError *error = nil;
    NSArray *fetchCount = [context executeFetchRequest:request error:&error];
    int pageCount = [fetchCount count];
    for (int i=0; i<pageCount; i++)
    {
        PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
        CGRect rect = scroller.frame;
        rect.size.height = scroller.frame.size.height;
        rect.size.width = scroller.frame.size.width;
        rect.origin.x = scroller.frame.origin.x + scrollWidth;
        rect.origin.y = scroller.frame.origin.y;
        pvc.view.frame  = rect;
        [pvc view];
        pvc.label.text = [NSString stringWithFormat:@"%d", pageNumber];
        pvc.label.textColor = [UIColor redColor];
        Photo *photo = [[Photo alloc] init];
        photo = [fetchCount objectAtIndex:i];
        UIImage *fetchedImage = [UIImage imageWithData:photo.photo];
        pvc.imageView.image = fetchedImage;
        [scroller addSubview:pvc.view];
        [pvc release];
        pageNumber++;
        scrollWidth += scroller.frame.size.width;
    }
    pageControl.numberOfPages=pageCount;
    pageControl.currentPage=0;
    [self.view addSubview:scroller];
}

...

@end

如果我将我的 CoreDataProjAppDelegate 导入到这些文件中的每一个并使用NSManagedObjectContext *context = [(CoreDataProjAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];,那么它可以正常工作。但这是正确的方法吗?

【问题讨论】:

    标签: ios core-data uiviewcontroller nsmanagedobjectcontext


    【解决方案1】:

    您必须设置 PersistentStoreCoordinator 才能使上下文有效:

    NSPersistentStoreCoordinator *psc = ((CoreDataProjAppDelegate *)[UIApplication sharedApplication].delegate).persistentStoreCoordinator;
        NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
        [context setPersistentStoreCoordinator:psc];
    

    这是假设您在应用程序委托上有一个名为 persistentStoreCoordinator 的属性,默认核心数据项目将拥有该属性。 psc 基本上是您的上下文(便笺簿)和实际持久存储(物理数据库)之间的链接。

    【讨论】:

    • 谢谢维尼。我确实有这个属性(即@synthesize persistentStoreCoordinator=__persistentStoreCoordinator;)...我是否需要在每个引用 ManagedObjectContext 的 UIViewController 中设置它?还是我只是在 AppDelegate 的“didFinishLaunchingWithOptions”方法中设置它?或者别的地方?我仍然有点不清楚这应该去哪里。
    • 只需要在新建或重新分配时设置。例如,我认为默认核心数据项目在创建您在 AppDelegate 中使用的主要上下文时会执行此操作。但是,如果您需要创建一个全新的,则必须进行设置。因此,如果您只是重用了 AppDelegate 中的上下文,那么您就不必设置它,因为它在创建时就已经设置好了。有意义吗?
    • 啊,我明白了。是的,这是有道理的:-)谢谢你把它分解并让它容易消化@Vinnie :-)
    【解决方案2】:

    您创建项目时是否勾选了“使用核心数据”框?如果你这样做了,你将自动拥有一个 managedObjectContext,然后你将它传递给任何其他需要它的类。

    【讨论】:

    • 嘿holografix,感谢您的回复。我确实勾选了“使用核心数据”框。我认为我没有自动拥有 managedObjectContext 。我将如何检查?因为如果我真的自动拥有它,那就太好了。
    • 它提供模板代码,查找该代码。它可能会懒惰地创建它并位于应用程序委托或根控制器上
    • 谢谢 bshirley。你,holografix 和 Vinnie(从上面)都在谈论同一件事吗?因为我正在研究 persistentStoreCoordinator 示例来解决这个问题。 -最佳内特
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 2023-03-30
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多