我有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的位置之外我什么都没改变
答案 0 :(得分:3)
我的猜测是你在某个地方有一个NSManagedObjectContextObjectsDidChangeNotification并且当你的目标被解除分配时你没有正确地移除观察者,所以当一个通知到达时,观察者试图在前一个目标的地址上使用通知新对象,这就是为什么它显示无法识别的选择器消息