Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old May 11, 2011, 05:30 AM   #1
Soulstorm
macrumors 68000
 
Soulstorm's Avatar
 
Join Date: Feb 2005
Core Data Problem

I made an application without Core Data, and I decided to implement Core Data afterwards.

I created the entities inside the model, and created the files for these entities.

However, whenever I call any property for these properties, I get a runtime error saying that the selector could not be recognized.

This is the source for the managed object:

Code:
@class CacheDB;

@interface CachedFile : NSManagedObject {

}
@property (nonatomic, retain) NSString * fileID;
@property (nonatomic, retain) NSString * filePath;
@property (nonatomic, retain) NSString * url;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) CacheDB * database;

@end

@implementation CachedFile
@dynamic fileID;
@dynamic filePath;
@dynamic url;
@dynamic date;
@dynamic database;


@end
and this is the creation code:
Code:
CachedFile *newCachedFile = (CachedFile *)[NSEntityDescription entityForName:@"CachedFile" inManagedObjectContext:context];
newCachedFile.url = downloader.url; //program crashes here...
Any ideas of what I might have missed or what I may be doing wrong?
Attached Thumbnails
Click image for larger version

Name:	Screen shot 2011-05-11 at 1.27.54 PM.png
Views:	75
Size:	35.5 KB
ID:	284912  
Soulstorm is offline   0 Reply With Quote
Old May 11, 2011, 06:10 AM   #2
jiminaus
macrumors 65816
 
Join Date: Dec 2010
Location: Sydney
Quote:
Originally Posted by Soulstorm View Post
Code:
CachedFile *newCachedFile = (CachedFile *)[NSEntityDescription entityForName:@"CachedFile" inManagedObjectContext:context];
newCachedFile.url = downloader.url; //program crashes here...
The code above isn't right. Sending entityForName:inManagedObjectContext: doesn't get you a managed object. It gets you an NSEntityDescription object. This object just contains the metadata directly from the model. It analogous to a class. You then use this to init an actually managed object.

Try this code instead.

Code:
NSEntityDescription *cachedFileEntityDescription =
   [NSEntityDescription entityForName:@"CachedFile"
               inManagedObjectContext:context];
CachedFile *newCachedFile = 
   [[CachedFile alloc] 
        initWithEntity:cachedFileEntityDescription
        insertIntoManagedObjectContext:context];
newCachedFile.url = downloader.url;
jiminaus is offline   0 Reply With Quote
Old May 11, 2011, 06:23 AM   #3
Soulstorm
Thread Starter
macrumors 68000
 
Soulstorm's Avatar
 
Join Date: Feb 2005
Quote:
Originally Posted by jiminaus View Post
The code above isn't right. Sending entityForName:inManagedObjectContext: doesn't get you a managed object. It gets you an NSEntityDescription object. This object just contains the metadata directly from the model. It analogous to a class. You then use this to init an actually managed object.

Try this code instead.

Code:
NSEntityDescription *cachedFileEntityDescription =
   [NSEntityDescription entityForName:@"CachedFile"
               inManagedObjectContext:context];
CachedFile *newCachedFile = 
   [[CachedFile alloc] 
        initWithEntity:cachedFileEntityDescription
        insertIntoManagedObjectContext:context];
newCachedFile.url = downloader.url;
I will never EVER post a question in the forums after 12 hours of work again. Thank you for the answer. I also have another question, more complex, but I will post it after I get some sleep . Sorry for wasting your time.
Soulstorm is offline   0 Reply With Quote
Old May 12, 2011, 07:21 AM   #4
Soulstorm
Thread Starter
macrumors 68000
 
Soulstorm's Avatar
 
Join Date: Feb 2005
I have another question:

I managed to run the application using the code you suggested and it runs ok the first time, but the second time it opens (and uses the already created files) it doesn't work. Here is my CacheDB object:

Code:
@class CachedFile;

@interface CacheDB : NSManagedObject {
@private
}
@property (nonatomic, retain) NSDate * dateModified;
@property (nonatomic, retain) NSSet* cachedFiles;

- (void)addCachedFilesObject:(CachedFile *)value;
- (void)removeCachedFilesObject:(CachedFile *)value;
- (void)addCachedFiles:(NSSet *)value;
- (void)removeCachedFiles:(NSSet *)value;
@end

@implementation CacheDB
@dynamic dateModified;
@dynamic cachedFiles;

- (void)addCachedFilesObject:(CachedFile *)value {    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    [self willChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"cachedFiles"] addObject:value];
    [self didChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [changedObjects release];
}

- (void)removeCachedFilesObject:(CachedFile *)value {
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    [self willChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"cachedFiles"] removeObject:value];
    [self didChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    [changedObjects release];
}

- (void)addCachedFiles:(NSSet *)value {    
    [self willChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
    [[self primitiveValueForKey:@"cachedFiles"] unionSet:value];
    [self didChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
}

- (void)removeCachedFiles:(NSSet *)value {
    [self willChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
    [[self primitiveValueForKey:@"cachedFiles"] minusSet:value];
    [self didChangeValueForKey:@"cachedFiles" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
}


@end
Here is some code that is supposed to return an existing CacheDB object and if there is none, create it:

Code:
- (CacheDB *)applicationDatabase
{
	if (applicationDatabase == nil) {
		NSLog(@"getting database..");
		NSManagedObjectContext *appContext = [[SFGlobals sharedSFGlobals]applicationManagedObjectContext];
		NSEntityDescription *desc = [NSEntityDescription entityForName:@"CacheDB" inManagedObjectContext:appContext];
		NSFetchRequest *request = [[NSFetchRequest alloc]init];
		[request setEntity:desc];
		NSArray *fetchResults = [appContext executeFetchRequest:request error:nil];
		[request release];
		if ([fetchResults count] <= 0) {
			NSLog(@"There is no database yet. Creating one now...");
			//perhaps this is a memory leak or a bug?
			CacheDB *newDatabase = (CacheDB *)[NSEntityDescription insertNewObjectForEntityForName:@"CacheDB" inManagedObjectContext:appContext];
			newDatabase.dateModified = [NSDate date];
			applicationDatabase = newDatabase;
			
		}else{
			NSLog(@"found database. inserting into variable and returning it...");
			applicationDatabase = (CacheDB *)[fetchResults objectAtIndex:0];
		}
	}
	NSLog(@"database contains %i items", [applicationDatabase.cachedFiles count]);
	return applicationDatabase;
}
The application runs ok and adds files using this code:

Code:
- (void)createDataForURL:(NSString *)url withData:(NSData *)data
{
	NSLog(@"creating data for url: %@", url);
	if ( ![self itemAlreadyExistsForURL:url] ) {
		NSLog(@"creating item...");
		CachedFile *newCachedFile = (CachedFile *)[NSEntityDescription insertNewObjectForEntityForName:@"CachedFile" inManagedObjectContext:[[SFGlobals sharedSFGlobals]applicationManagedObjectContext]];
		newCachedFile.url = url;
		newCachedFile.date = [NSDate date];
		newCachedFile.fileID = [self generateFileID];
		newCachedFile.filePath = [[self applicationDatabaseFolder]stringByAppendingPathComponent:newCachedFile.fileID];
		[self addCachedtoDatabase:newCachedFile];
		[data writeToFile:newCachedFile.filePath atomically:NO];
	}else{
		NSLog(@"item for %@ already exists. Nothing done", url);
	}
}
When I start the program second time, it crashes in the following line:
NSLog(@"database contains %i items", [applicationDatabase.cachedFiles count]);

and it complains about an unrecognized selector sent to NSDictionary.

Any ideas?
Soulstorm is offline   0 Reply With Quote
Old May 12, 2011, 02:51 PM   #5
chown33
macrumors 603
 
Join Date: Aug 2009
Post the stack trace.

Post the complete error message for the unrecognized selector.


With or without garbage collection?

If without, have you done a Build and Analyze, and have you run under Instruments with zombies enabled?
chown33 is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
thread Thread Starter Forum Replies Last Post
core data binding not working Javajax Mac Programming 3 Jul 10, 2011 01:23 PM
Resolved: Struggling with Core Data: Part 2 RonC iPhone/iPad Programming 2 May 27, 2011 01:02 PM
Help Needed - Xcode 4 Options: Use Core Data Include Unit Tests Mitch1984 iPhone/iPad Programming 3 Feb 26, 2011 03:42 PM
simple core data problem medasmx iPhone/iPad Programming 0 Nov 2, 2010 02:51 AM
Core Data problem stijnschoor Mac Programming 2 Jun 7, 2008 12:29 PM


All times are GMT -5. The time now is 02:52 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC