除了在 *.h 文件中的接口中声明之外,如何使从 NSManagedObject 子类化的对象的选择器对编译器可见?

Posted

技术标签:

【中文标题】除了在 *.h 文件中的接口中声明之外,如何使从 NSManagedObject 子类化的对象的选择器对编译器可见?【英文标题】:How make selector of an object subclassed from NSManagedObject visible to the compiler, beyond declaring in the interface in *.h file? 【发布时间】:2011-04-05 02:13:41 【问题描述】:

核心数据,NSManagedObject,

我从 MacResearch.org 获得了一个名为 Molecular Core 的演示应用程序的源代码

有一个名为 Molecule 的类。它是 NSManagedObject 的子类。 当我尝试在 Molecule 的实例上调用实例方法时 我在下面的 NSLog 消息之后收到“无法识别的选择器”错误消息:

2011-04-04 20:41:44.778 分子核心[13766:903] 符号=Ag 分子=(实体:分子;ID:0x1230b70;数据: 原子 = ( ); name = "新分子"; ) 坐标[1]=2.500000


2011-04-04 20:41:45.917 分子核心[13766:903]-[NSManagedObject addAtomWithPosition:andSymbol:]: 无法识别的选择器发送到实例 0x1234d00


这是我的问题:

Molecule.h 声明方法 addAtomWithPosition:andSymbol: 与 Molecule.m 中的定义相同。 为什么系统找不到这个方法。 Molecule 的实例似乎仅被视为 其超类 NSManagedObject 的一个实例。这是为什么呢?

感谢阅读! 标记

//
//  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

【问题讨论】:

【参考方案1】:

NSManagedObject 不响应选择器,但 NSManagedObject 的子类 Molecule 会。您需要在 Core Data 模型中将实体 Molecule 的类设置为 Molecule 类。

【讨论】:

完全正确!非常感谢。 forrst.com/posts/…

以上是关于除了在 *.h 文件中的接口中声明之外,如何使从 NSManagedObject 子类化的对象的选择器对编译器可见?的主要内容,如果未能解决你的问题,请参考以下文章

java中native的用法

IOS:如何使从 nib 文件加载的子视图可以使用它的按钮(IBAction)

6.3 特殊字符串

除了在 web.xml 中声明过滤器之外,还有啥方法可以指定过滤器的顺序吗?

如何在build.gradle之外声明存储库详细信息

使用“#define FOO”而没有分配任何值——除了包括警卫之外?