How make selector of an object subclassed from NSManagedObject visible to the compiler, beyond declaring in the interface in *.h file?
Core Data, NSManagedObject,
I obtained source code for a demo app from MacResearch.org named Molecular Core
There is a class named Molecule. It is a subclass of NSManagedObject. When I try to invoke an instance method on an instance of Molecule I g开发者_StackOverflow中文版et an 'unrecognized selector' error message following an NSLog message just below:
2011-04-04 20:41:44.778 Molecular Core[13766:903] symbol=Ag molecule= (entity: Molecule; id: 0x1230b70 ; data: { atoms = ( ); name = "New Molecule"; }) coords[1]=2.500000
2011-04-04 20:41:45.917 Molecular Core[13766:903] -[NSManagedObject addAtomWithPosition:andSymbol:]: unrecognized selector sent to instance 0x1234d00
THIS IS MY QUESTION:
Molecule.h declares the method- addAtomWithPosition:andSymbol: identically to the definition in Molecule.m. Why does the system fail to find this method. The instance of Molecule seems to be regarded solely as an instance of its superclass NSManagedObject . Why is that?
Thanks for reading! Mark
//
// Molecule.h
// Molecular Core
#import <Foundation/Foundation.h>
@class Atom;
@interface Molecule : NSManagedObject {
@private
}
@property (readwrite, copy) NSString *name;
/// THIS SELECTOR/METHOD IS 'INVISIBLE' TO COMPILER //////
-(id)addAtomWithPosition:(double *)position andSymbol:(NSString *)symbol;
/// THIS CLASS METHOD IS VISIBLE TO COMPILER' //////
+(id)moleculeFromXYZString:(NSString *)xyzString withName:(NSString *)name
inManagedObjectContext:(NSManagedObjectContext *)context;
@end
/// end molecule.h /////////////////
// begin molecule.m /////////////
//
// Molecule.m
#import "Molecule.h"
#import "Atom.h"
#import "Element.h"
@implementation Molecule
@dynamic name;
-(id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
//// THIS CLASS METHOD RUNS ////////////
+(id)moleculeFromXYZString:(NSString *)xyzString
withName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
{
Molecule *molecule;
molecule = (Molecule*) [NSEntityDescription insertNewObjectForEntityForName:@"Molecule"
inManagedObjectContext:context];
molecule.name = name;
NSScanner *scanner = [NSScanner scannerWithString:(nil == xyzString ? @"" : xyzString)];
[scanner setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
BOOL xyzLine = NO;
BOOL firstLineFound = NO;
NSCharacterSet *newlineSet;
newlineSet = [NSCharacterSet characterSetWithCharactersInString:@"\n"];
while ( ![scanner isAtEnd] && ( ( xyzLine && firstLineFound ) || !firstLineFound ) )
{
NSString *line = nil;
NSScanner *lineScanner;
double coords[3];
NSString *symbol;
if ( ![scanner scanUpToCharactersFromSet:newlineSet intoString:&line] )
line = @"";
[scanner scanString:@"\n" intoString:NULL];
lineScanner = [NSScanner scannerWithString:line]; // Create scanner for scanning line content
[lineScanner setCharactersToBeSkipped:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
xyzLine = [lineScanner scanCharactersFromSet:[NSCharacterSet letterCharacterSet] intoString:&symbol] &&
[lineScanner scanDouble:&(coords[0])] &&
[lineScanner scanDouble:&(coords[1])] &&
[lineScanner scanDouble:&(coords[2])];
NSLog(@"symbol=%@\nmolecule=%@\ncoords[1]=%f",symbol,molecule,(coords[1]));
if ( xyzLine ) {
firstLineFound = YES;
//// THIS IS THE CALL THAT FAILS /////////////////////
[((Molecule*)molecule) addAtomWithPosition:(double *)coords andSymbol:(NSString*)symbol];
}
}
return molecule;
}
-(id)addAtomWithPosition:(double *)position andSymbol:(NSString *)symbol {
Atom *atom = [NSEntityDescription insertNewObjectForEntityForName:@"Atom"
inManagedObjectContext:[self managedObjectContext]];
Element *element = [Element elementWithSymbol:symbol inManagedObjectContext:[self managedObjectContext]];
atom.molecule = self;
atom.element = element;
atom.positionX = [NSNumber numberWithDouble:position[0]];
atom.positionY = [NSNumber numberWithDouble:position[1]];
atom.positionZ = [NSNumber numberWithDouble:position[2]];
NSLog(@"positionY=%@",atom.positionY);
return atom;
}
-(void)dealloc
{
[super dealloc];
}
@end
NSManagedObject
doesn't respond to the selector, but your subclass Molecule
of NSManagedObject
does. You need to set the class for the entity Molecule
to the class Molecule
in your Core Data model.
精彩评论