Problem with entityForName & ManagedObjectContext when extending tutorial material - iphone

Afternoon all,
I tried to add a second data entity to the persistent store in the (locations) coredata tutorial code, and then access this in a new view. I think that I've followed the tutorial, and checked that I'm doing a clean build etc, but can't see what to change to prevent it crashing.
I'm afraid I'm at my wits end with this one, and can't seem to find the step that I've missed. I've pasted the header and code files below, please let me know if I need to share any more of the code. The crash seems to happen on the line:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:[self managedObjectContext]];
There is one other line in the code that refers to galleryviewcontroller at the moment, and that's in the main application delegate:
galleryViewController.managedObjectContext = [self managedObjectContext];
GalleryViewController.h
#import <UIKit/UIKit.h>
#interface GalleryViewController : UIViewController {
NSManagedObjectContext *managedObjectContext;
int rowNumber;
IBOutlet UILabel *lblMessage;
UIBarButtonItem *addButton;
NSMutableArray *imagesArray;
}
#property (readwrite) int rowNumber;
#property (nonatomic,retain) UILabel *lblMessage;
#property (nonatomic,retain) NSMutableArray *imagesArray;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain) UIBarButtonItem *addButton;
-(void)updateRowNumber:(int)theIndex;
-(void)addImage;
#end
GalleryViewController.m
#import "RootViewController.h"
#import "LocationsAppDelegate.h"
#import "Album.h"
#import "GalleryViewController.h"
#import "Image.h"
#implementation GalleryViewController
#synthesize lblMessage,rowNumber,addButton,managedObjectContext;
#synthesize imagesArray;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
-(void)updateRowNumber:(int)theIndex{
rowNumber=theIndex;
LocationsAppDelegate *mainDelegate =(LocationsAppDelegate *)[[UIApplication sharedApplication] delegate];
Album *anAlbum = [mainDelegate.albumsArray objectAtIndex:rowNumber];
lblMessage.text = anAlbum.uniqueAlbumIdentifier;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addImage)];
addButton.enabled = YES;
self.navigationItem.rightBarButtonItem = addButton;
/* Found this in another answer, adding it to the code didn't help.
if (managedObjectContext == nil) {
managedObjectContext = [[[UIApplication sharedApplication] delegate] managedObjectContext];
}
*/
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];
// Order the albums by creation date, most recent first.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"imagePath" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[self setImagesArray:mutableFetchResults];
int a = 5;
int b = 10;
for( int i=0; i<[imagesArray count]; i++ )
{
if( a == 325 )
{
a = 5;
b += 70;
}
UIImageView *any = [[UIImageView alloc] initWithFrame:CGRectMake(a,b,70,60)];
any.image = [imagesArray objectAtIndex:i];
any.tag = i;
[self.view addSubview:any];
[any release];
a += 80;
}
}
-(void)addImage{
NSString *msg = [NSString stringWithFormat:#"%i",rowNumber];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Add image to" message:msg
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
- (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.
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[lblMessage release];
[managedObjectContext release];
[super dealloc];
}
#end

It helps to post the error you are getting.
Have you tried the following:
Clean build of your project
Resetting the simulator to remove the older sqlite data file
If neither of those solve the issue then post the error you are getting as an update to your question.
update
The information I was looking for would be printing out in the console, while the debugger is an infinitely useful tool and I recommend learning it, in this case your issue would have been resolved by reviewing the console output of your application.

Related

Tab Bar appearing with no items

I worked CoreData into my Tab Bar app and the CoreData functions are working (i.e. I can output information from it to the console). The problem is that my tab bar isn't working. When I run my app, it looks like this:
It looks as if the tab bar itself is showing up but there aren't any items and it isn't displaying the table view. My storyboard looks like this:
Here is the code for my AppDelegate:
AppDelegate.h
#import <UIKit/UIKit.h>
#import "JobsViewController.h"
#import "Job.h"
#import "Shift.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"
#implementation AppDelegate
#synthesize window = _window;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize managedObjectModel = __managedObjectModel;
#synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSManagedObjectContext *context = [self managedObjectContext];
Job *job = [NSEntityDescription insertNewObjectForEntityForName:#"Job" inManagedObjectContext:context];
job.employer = #"Calder Centre";
job.jobTitle = #"Addictions Counsellor";
job.regularRate = 25.9f;
job.overtimeRate = 30.5f;
job.deduction1 = 0.1f;
job.deduction2 = 0.2f;
job.deduction3 = 0.3f;
job.deduction4 = 0.4f;
job.deduction1Name = #"CPP";
job.deduction2Name = #"IT";
job.deduction3Name = #"Union Dues";
job.deduction4Name = #"Other";
Shift *shift = [NSEntityDescription insertNewObjectForEntityForName:#"Shift" inManagedObjectContext:context];
shift.startDate = [NSDate date];
shift.endDate = [NSDate date];
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
// Test listing all FailedBankInfos from the store
NSFetchRequest *jobFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *jobEntity = [NSEntityDescription entityForName:#"Job" inManagedObjectContext:context];
[jobFetchRequest setEntity:jobEntity];
NSArray *fetchedJobs = [context executeFetchRequest:jobFetchRequest error:&error];
for (Job *job in fetchedJobs) {
NSLog(#"Employer: %#", job.employer);
NSLog(#"Title: %#", job.jobTitle);
}
NSFetchRequest *shiftFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *shiftEntity = [NSEntityDescription entityForName:#"Shift" inManagedObjectContext:context];
[shiftFetchRequest setEntity:shiftEntity];
NSArray *fetchedShifts = [context executeFetchRequest:shiftFetchRequest error:&error];
for (Shift *shift in fetchedShifts) {
NSLog(#"Start Date: %#", shift.startDate);
NSLog(#"End Date: %#", shift.endDate);
}
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UITabBarController *tabBarController = [[UITabBarController alloc]init];
self.window.rootViewController = tabBarController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Here is the view controller:
JobsViewController.h
#import <UIKit/UIKit.h>
#import "Job.h"
#import "Shift.h"
#interface JobsViewController : UITableViewController
#property (nonatomic, strong) NSManagedObjectContext* managedObjectContext;
#property (nonatomic, strong) NSArray *listOfJobs;
#end
JobsViewController.m
#import "JobsViewController.h"
#interface JobsViewController ()
#end
#implementation JobsViewController
#synthesize managedObjectContext, listOfJobs;
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Job" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
self.listOfJobs = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
self.title = #"Jobs";
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [listOfJobs count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"job";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
Job *job = [listOfJobs objectAtIndex:indexPath.row];
cell.textLabel.text = job.jobTitle;
cell.detailTextLabel.text = job.employer;
return cell;
}
This has nothing to do with core data.
You are using code from an app delegate template for a non-storyboard project, but you are using a storyboard. The code in your didFinishLaunching method is creating a new window and empty tab bar controller, which is overriding anything from your storyboard.
Get rid of everything after self.window =, except return YES;. This is code used in xib-based applications and is not necessary if you have a storyboard.

I am unable to copy my NSMutable array to appDelegate_iPhone array(Universal app)

Actually I have parsed an XML and store URL's of images as an NSMutableArray object, but I want this array to be used in another ViewController (to give to UIImage in UIImageView to show Images at runtime), so I am trying to copy that Mutable array to myAppDelegate_iPhone's NSMutableArray. And I want to again copy that Appdelegate's array to my next or other ViewControllers NSMutableArray.
so can anyone help me out pleaseeeeee? Here is my code :-
code:-
#class FirstViewController;
#interface AppDelegate_iPhone : NSObject <UIApplicationDelegate> {
UIWindow *window;
FirstViewController *viewController;
NSMutableArray *logoArray;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) NSMutableArray *logoArray;
#end
#import "AppDelegate_iPhone.h"
#import "FirstViewController.h"
#import "ParsingViewController.h"
#implementation AppDelegate_iPhone
#synthesize window,logoArray;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
viewController = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
NSURL *url = [[NSURL alloc] initWithString:#"http://litofinter.es.milfoil.arvixe.com/displayxml1.aspx"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
ParsingViewController *parser = [[ParsingViewController alloc] init];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
logoArray = [[NSMutableArray alloc]init];
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
// dealloc done
#end
#class Litofinter,AppDelegate_iPhone;
#interface ParsingViewController : NSObject<NSXMLParserDelegate> {
NSString *myString;
NSMutableArray *myMutableArray;
Litofinter *obj;
NSString *currentElement;
AppDelegate_iPhone *appDelegate;
}
#import "ParsingViewController.h"
#import "Litofinter.h"
#import "AppDelegate_iPhone.h"
#implementation ParsingViewController
#synthesize myMutableArray, myString;
-(id)init{
if(self == [super init]){
myMutableArray = [[NSMutableArray alloc] init];
}
return self;
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
//myMutableArray = [[NSMutableArray alloc]init];
}
// Parsing done here
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
//UIApplication *app = [UIApplication sharedApplication];
//appDelegate=app.delegate;
appDelegate.logoArray = [[NSMutableArray alloc]initWithArray:myMutableArray];
NSLog(#"appDelegate.logoArray count %d",[appDelegate.logoArray count]);
for (Litofinter *lito in appDelegate.logoArray) {
NSLog(#"Array Elements :----- %#",lito.cLogo);
}
}
#end
#import <UIKit/UIKit.h>
#class AppDelegate_iPhone,Litofinter,ParsingViewController;
#interface FirstViewController : UIViewController {
NSMutableArray *array;
//Litofinter *lito;
NSString *logoString;
AppDelegate_iPhone *appDelegate;
ParsingViewController *obj;
}
#end
#import "FirstViewController.h"
#import "AppDelegate_iPhone.h"
#import "Litofinter.h"
#import "ParsingViewController.h"
#implementation FirstViewController
-(id)init{
if(self == [super init]){
obj = [[ParsingViewController alloc] init];
array = [[NSArray alloc] initWithArray: obj.myMutableArray];
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
int x=5,y=10;
appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
// UIApplication *app = [UIApplication sharedApplication];
// appDelegate=app.delegate;
NSLog(#"delegate Array ====== %d",[appDelegate.logoArray count]);
NSLog(#"New Array ====== %d",[obj.myMutableArray count]);
/*
array = [[NSMutableArray alloc]initWithArray:appDelegate.logoArray];
NSLog(#"array at 0 ===== %#",[array objectAtIndex:0]);
for (Litofinter *lito1 in obj.myMutableArray) {
NSLog(#"Array Elements in Lito1 are :------------- %#",lito1.cLogo);
}
for (Litofinter *lito2 in array) {
NSLog(#"Array Elements in Lito1 are :------------- %#",lito2.cLogo);
}
*/
for (Litofinter *lito in obj.myMutableArray) {
//for (int i=0; i<[appDelegate.logoArray count]; i++) {
// lito.cLogo = [array objectAtIndex:i];
NSLog(#"%#",lito.cLogo);
UIImage *imageFromUrl = [UIImage imageWithContentsOfFile:[NSURL fileURLWithPath:lito.cLogo]];
UIImageView *imgView = [[UIImageView alloc] initWithImage:imageFromUrl];
[imgView setFrame:CGRectMake(x, y, 196, 90)];
[self.view addSubview:imgView];
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTapImage)];
[imgView addGestureRecognizer:tgr];
// [tgr release];
//Do the rest of your operations here, don't forget to release the UIImageView
x = x + 200;
}
}
-(void)onTapImage
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Message from mAc" message:#"Trail" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
[alert show];
}
- (void)dealloc {
[super dealloc];
}
#end
You can use this.
UIImage *imageFromUrl = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:lito.cLogo]]];

Why doesn't my program enter the viewDidLoad method?

I am trying to test this program on use of Core data. Once again, this is an example from the Dave Marks book. It has four text fields on a view and it loads it by using core data to connect to the database.
The app was created as a window based application and then I added a viewController to it. The file's owner is a sub class of the custom viewController class that I have created.
When I execute it, the UIView comes up with a blank view with no text boxes or labels that I had created in the view.
I put a break point in the main method, it does not even go anywhere from there when I click on step into method button. When I place a break point on the viewDidLoad method, it does not even get to it.
Lastly I do not get any errors on the console. What is going on?
Here is the viewController class:
#import "PersistenceViewController.h"
#import "CoreDataPersistenceAppDelegate.h"
#implementation PersistenceViewController
#synthesize line1;
#synthesize line2;
#synthesize line3;
#synthesize line4;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
CoreDataPersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Line" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"There was an error");
}
for (NSManagedObject *oneObject in objects) {
NSNumber *lineNum = [oneObject valueForKey:#"lineNum"];
NSString *lineText = [oneObject valueForKey:#"lineText"];
NSString *fieldName = [NSString stringWithFormat:#"line%d", [lineNum integerValue]];
UITextField *theField = [self valueForKey:fieldName];
theField.text = lineText;
}
[request release];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(void) applicationWillResignActive:(NSNotification *)notification {
CoreDataPersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
for (int i=1; i<=4; i++) {
NSString *fieldName = [NSString stringWithFormat:#"line%d",i];
UITextField *theField = [self valueForKey:fieldName];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Line" inManagedObjectContext:context];
[request setEntity:entityDescription];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(lineNum = %d)", i];
[request setPredicate:pred];
NSManagedObject *theLine = nil;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"There was an error");
}
if ([objects count] > 0)
theLine = [objects objectAtIndex:0];
else
theLine = [NSEntityDescription insertNewObjectForEntityForName:#"Line" inManagedObjectContext:context];
[theLine setValue:[NSNumber numberWithInt:i] forKey:#"lineNum"];
[theLine setValue:theField.text forKey:#"lineText"];
[request release];
}
[context save:&error];
}
- (void)viewDidUnload
{
self.line1 = nil;
self.line2 = nil;
self.line3 = nil;
self.line4 = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[line1 release];
[line2 release];
[line1 release];
[line1 release];
[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.
}
#end
Be sure to change the viewcontroller that gets intialized in the appdelegate with the correct nib. The blank UIView is probably the view created when you started the project.
In your AppDelegate there is a method called applicationdidFinishLaunchingWithOptions, in which something like the following code is located:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[RIViewController alloc] initWithNibName:#"RIViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
In my case I load the RIViewController. By default the nib file has the same name as the controller and is hence named RIViewController aswell.

NSFetchedResultsController objectAtIndexPath crash (EXC_BAD_ACCESS)

I have a huge problem with NSFetchedResultsCOntroller. I'm using fetchedResultsContrioller and I have interface with 3 tabs. They use Core Data too. But I have a problem with only ONE of them.
Faktura *faktura = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = faktura.NumerFV; // THE CRASH IS HERE
int productsCount = [faktura.Produkty count]; // OR HERE
NSString *kontrahentName = [faktura.Kontrahent valueForKey:#"NazwaKrotka"]; // OR HERE
cell.detailTextLabel.text = [NSString stringWithFormat:#"nabywca: %#, produktów: %d",kontrahentName, productsCount];
cell.imageView.image = [UIImage imageNamed:#"faktura_cell_image.png"];
cell.hidesImageWhileEditing = YES;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Faktura is my NSManagedObject subclass.
NSZombie says:
-[CFDictionary retain]: message sent to deallocated instance 0x5d619d0
My fetchedResultsController implementation:
- (NSFetchedResultsController *)fetchedResultsController {
if (__fetchedResultsController != nil) return __fetchedResultsController;
// Setup the table
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Faktura" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Setup the sort descriptors
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"DataWystawienia" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create the fetched results controller
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) { // THE CRASH IS HERE UNLESS I INIT NSFetchedResultsController WITH cacheName:nil. (IF IT'LL BE cacheName:#"Root" IT CRASHES.)
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Błąd Krytyczny" message:#"Wystąpił nieznany błąd przy zmienianiu zawartości w bazie danych. Dla dobra twoich danych prosimy niezwłocznie wyjść z aplikacji i spróbować ponownie." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __fetchedResultsController;
}
Faktura.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface NSArrayToDataTransformer : NSValueTransformer #end
#interface NSDictionaryToDataTransformer : NSValueTransformer #end
#interface Faktura : NSManagedObject
#property (nonatomic, retain) NSDate * DataZaplaty;
#property (nonatomic, retain) NSString * NumerFV;
#property (nonatomic, retain) NSDate * DataWystawienia;
#property (nonatomic, retain) NSDate * DataSprzedazy;
#property (nonatomic, retain) id Produkty;
#property (nonatomic, retain) id Kontrahent;
#end
Faktura.m
#import "Faktura.h"
#implementation Faktura
#dynamic DataZaplaty;
#dynamic NumerFV;
#dynamic DataWystawienia;
#dynamic DataSprzedazy;
#dynamic Produkty;
#dynamic Kontrahent;
+ (void)initialize {
if (self == [Faktura class] ) {
NSArrayToDataTransformer *arrayTransformer = [[NSArrayToDataTransformer alloc] init];
[NSValueTransformer setValueTransformer:arrayTransformer forName:#"NSArrayToDataTransformer"];
NSDictionaryToDataTransformer *dictTransformer = [[NSDictionaryToDataTransformer alloc] init];
[NSValueTransformer setValueTransformer:dictTransformer forName:#"NSDictionaryToDataTransformer"];
}
}
#end
#implementation NSArrayToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
return data;
}
- (id)reverseTransformedValue:(id)value {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [array autorelease];
}
#end
#implementation NSDictionaryToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
return data;
}
- (id)reverseTransformedValue:(id)value {
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [dict autorelease];
}
#end
My Faktura object insertion code
- (void)fakturaCreator:(FakturaCreator *)form didEndWithValues:(NSDictionary *)values {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
Faktura *newFaktura = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newFaktura setNumerFV:[values valueForKey:#"id"]];
[newFaktura setDataWystawienia:[values valueForKey:#"creationDate"]];
[newFaktura setDataSprzedazy:[values valueForKey:#"sellDate"]];
[newFaktura setDataZaplaty:[values valueForKey:#"paymentDate"]];
[newFaktura setKontrahent:[values valueForKey:#"kontrahent"]];
[newFaktura setProdukty:[values valueForKey:#"produkty"]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[self.emptySectionView setHidden:YES];
}
FakturaCreator is my UIViewController where user create an invoice. values array contains dictionary of values: my invoice number (NSString), various dates (NSDate), client (NSDictionary) and products (NSArray).
Please help me!
If you want some additional code, i'll put it here.
EDIT: It is definetly objectAtIndexPath: fault. When I comment all the cell setup code (it will display empty cell) and then try to remove the cell, app crashes on line which contains objectatIndexPath:.
EDIT #2: Anybody? Please, help me... :(
I think I see the problem. In your NSArrayToDataTransformer, you have this:
- (id)reverseTransformedValue:(id)value {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [array autorelease];
}
Since unarchiveObjectWithData: does not begin with "alloc", "new", "copy", or "mutableCopy", you do not own the object and therefore may not autorelease it. You have the same problem in your NSDictionaryToDataTransformer.
Your inclusion of the value transformers into the class and the using +initialize is non-standard. Although +initialize should work, it is recommended in the Core Data docs not use any kind of initialization methods at all but to rely on awakeFromFetch for initialization.
I would check your tableview methods such as numberOfRowsInSection: to ensure you are getting the right indexes back from the tableview. If the rows in the tableview and the count of the fetchedObjects array come out of sync, you can get this kind of crash.

Initialization problem

I have a problem.
This is my code.
When i try to use the IBAction SavePosition the "arrayPosition" isn't update.
Else if i initialize the "arrayPosition" in "SavePosition" the value is stored in the array.
Why this anomaly?
#import <UIKit/UIKit.h>
#interface AccelerometroViewController : UIViewController <UIAccelerometerDelegate, UITextFieldDelegate, UIAlertViewDelegate>{
//.....
NSMutableArray *arrayPosizioni;
NSMutableArray *arrayPosizioniCorrenti;
NSString *nomePosizioneCorrente;
}
-(IBAction)salvaPosizione;
//...
#property (nonatomic, assign) NSMutableArray *arrayPosizioni;
#property (nonatomic, assign) NSMutableArray *arrayPosizioniCorrenti;
#property (nonatomic, assign) NSString *nomePosizioneCorrente;
#end
#import "AccelerometroViewController.h"
#import "Position.h"
#implementation AccelerometroViewController
float actualX;
float actualY;
float actualZ;
#synthesize arrayPosition;
#synthesize arrayCurrentPosition;
#synthesize nameCurrentPosition;
-(id)init {
self = [super init];
if (self != nil) {
arrayPosition = [[NSMutableArray alloc]init];
arrayCurrentPosition = [[NSMutableArray alloc]init];
nameCurrentPosition = [NSString stringWithFormat:#"noPosition"];
actualX = 0;
actualY = 0;
actualZ = 0;
}
return self;
}
-(void)updateTextView:(NSString*)nomePosizione
{
NSString *string = [NSString stringWithFormat:#"%#", nameCurrentPosition];
textEvent.text = [textEvent.text stringByAppendingString:#"\n"];
textEvent.text = [textEvent.text stringByAppendingString:string];
}
-(IBAction)savePosition{
Posizione *newPosition;
newPosition = [[Position alloc]init];
if([newPosition setValue:(NSString*)fieldNomePosizione.text:(float)actualX:(float)actualY:(float)actualZ]){
//setValue is a method of Position. I'm sure that this method is correct
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Salvataggio Posizione" message:#"Posizione salvata con successo" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
[alert release];
[arrayPosition addObject:newPosition];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Salvataggio osizione" message:#"Errore nel salvataggio" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
Whats going on?
I bet you're creating your view controller inside a xib file?
If you set a breakpoint inside your init method on the line
arrayPosition = [[NSMutableArray alloc]init];
I bet it never runs. This means that when you get to the line
[arrayPosition addObject:newPosition];
arrayPosition is still nil so nothing happens.
How to fix it?
If you're initializing a UIViewController it's either called inside initWithNibName:bundle: if you've created it in code or in initWithCoder: if it's created inside a xib file.
You need to do something like this :
- (void) initialise {
arrayPosition = [[NSMutableArray alloc] init];
arrayCurrentPosition = [[NSMutableArray alloc] init];
nameCurrentPosition = #"noPosition";
actualX = 0;
actualY = 0;
actualZ = 0;
}
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
if (self = [super initWithNibName:nibName bundle:bundle]) {
[self initialise];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
[self initialise];
}
return self;
}
This will call initailise regardless of how the view controller is created.
This:
[newPosition setValue:(NSString*)fieldNomePosizione.text:(float)actualX:(float)actualY:(float)actualZ]
... is gibberish. I don't even see how it compiles. I assume its a typo. However, if the function does not return a boolean it will return a void pointer and always evaluate to false so the block is never called.
More generally, your problem is most likely that you are not using the self.propertyName notation to refer to your properties so they are not being retained. E.g.
[arrayPosition addObject:newPosition];
should be:
[self.arrayPosition addObject:newPosition];
... as should all other references to arrayPosition in the code.