保存到核心数据崩溃

时间:2015-02-04 16:05:40

标签: ios objective-c xcode core-data nsmanagedobjectcontext

我有2个类,PhotoCollectionviewController和AddPhotoViewController。 PhotoCollectionviewController是FetchResultViewController的子类。当AddPhotoViewController第一次出现在navigationController中时,我能够从库/相机(' AddPhotoViewController')中选择一张照片,并且我转向PhotoCollectionviewController。我已经交换了segues循环,所以PhotoCollectionviewController是第一个VC,但我现在收到错误。

CoreData:错误:严重的应用程序错误。在Core Data更改处理期间捕获到异常。这通常是NSManagedObjectContextObjectsDidChangeNotification的观察者中的错误。 - [__ NSCFData compare:]:无法识别的选择器使用userInfo(null)发送到实例0x7fa5b2d78480

PhotoCollectionViewController.h

    #import "FetchResultViewController.h"
    #import "PhotoCell.h"
    #import "ViewController.h"
    #import "AppDelegate.h"


@interface PhotoCollectionViewController : FetchResultViewController <UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,UIGestureRecognizerDelegate,UICollectionViewDataSource>

@property (strong, nonatomic) NSMutableArray *photoArray;

@property (strong, nonatomic) IBOutlet UICollectionView *photoDiaryCollectionView;

@end

PhotoCollectionViewController.m

#import "PhotoCollectionViewController.h"
#import "Photo.h"

@interface PhotoCollectionViewController ()

@end

@implementation PhotoCollectionViewController

@synthesize fetchResultsController = _fetchResultsController;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.photoArray =[[NSMutableArray alloc]init];


    self.photoDiaryCollectionView.delegate = self;
    self.photoDiaryCollectionView.dataSource = self;

    [NSFetchedResultsController deleteCacheWithName:@"Photos"];

    [self.fetchResultsController performFetch:nil];

    [self.photoDiaryCollectionView reloadData];

 //   [self getAllPhotos];
}

-(void)getAllPhotos
{
    for (Photo *aPhoto in self.fetchResultsController.fetchedObjects)

    {
          UIImage *image = [UIImage imageWithData:aPhoto.photoData];

        [self.photoArray  addObject:image];
    }
}

-(void) viewDidAppear:(BOOL)animated
{
    [self.photoDiaryCollectionView reloadData];
}

- (NSFetchedResultsController*)fetchResultsController

{
    if (_fetchResultsController == nil)

    {
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];
        NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"photoData" ascending:YES];
        [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
        fetchRequest.sortDescriptors = @[sort];

        _fetchResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.appDelegate.managedObjectContext sectionNameKeyPath:nil
                                                                                cacheName:@"Photos"];
        _fetchResultsController.delegate = self;
    }

    return _fetchResultsController;
}

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

-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}


- (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.fetchResultsController.fetchedObjects.count;
}

- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PhotoCell *cell = (PhotoCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];

    Photo *photo = [self.fetchResultsController objectAtIndexPath:indexPath];

    UIImage *image = [UIImage imageWithData:photo.photoData];

    [self.photoArray  addObject:[UIImage imageWithData:photo.photoData]];

    [cell loadCell:image];

    return cell;
}

- (CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
    return 4;
}

- (CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
    return 1;
}

- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{

}


/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

AddPhotoViewController.h

    #import "ViewController.h"
    #import "Photo.h"
    #import "AppDelegate.h"

@interface AddPhotoViewController : ViewController

@property (strong, nonatomic) IBOutlet UIImageView *photoImageView;

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

- (IBAction)saveButtonPressed:(id)sender;

- (IBAction)takePhotoButtonPressed:(id)sender;
- (IBAction)pickFromLibraryButtonPressed:(id)sender;

@end

AddPhotoViewController.m

#import "AddPhotoViewController.h"

@interface AddPhotoViewController ()

@property (nonatomic,strong) UIImage *currentImage;

@end

@implementation AddPhotoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

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

-(void)saveImage
{
    AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    _managedObjectContext = [delegate managedObjectContext];

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Photo"
                                                         inManagedObjectContext:self.managedObjectContext];

    Photo *photos  = (Photo*)[[NSManagedObject alloc]initWithEntity:entityDescription insertIntoManagedObjectContext:self.managedObjectContext];


    NSData *imageData = UIImagePNGRepresentation(self.currentImage);

    photos.photoData = imageData;

    //    [photos setPhotoData:imageData];

    [delegate saveContext];

}

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

      self.currentImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    [picker dismissViewControllerAnimated:YES completion:Nil];

    self.photoImageView.image = self.currentImage;

}


- (IBAction)saveButtonPressed:(id)sender
{
    [self saveImage];
//    [self performSegueWithIdentifier:@"ImageSaved" sender:self];

}

- (IBAction)takePhotoButtonPressed:(id)sender
{
    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeCamera] == NO))
        return;

    UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
    mediaUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    mediaUI.allowsEditing = NO;
    mediaUI.delegate = self;

    [self presentViewController:mediaUI animated:YES completion:nil];

}

- (IBAction)pickFromLibraryButtonPressed:(id)sender
{
    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypePhotoLibrary] == NO))
        return;

    UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
    mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    mediaUI.allowsEditing = NO;
    mediaUI.delegate = self;
    [self presentViewController:mediaUI animated:YES completion:nil];
}
@end

我真的不明白为什么这不起作用,除了导航控制器中VC的位置之外我什么都没改变

1 个答案:

答案 0 :(得分:3)

我的猜测是你在某个地方有一个NSManagedObjectContextObjectsDidChangeNotification并且当你的目标被解除分配时你没有正确地移除观察者,所以当一个通知到达时,观察者试图在前一个目标的地址上使用通知新对象,这就是为什么它显示无法识别的选择器消息