Xcode4:为自定义核心数据管理对象生成不同的代码

时间:2011-03-09 23:43:34

标签: iphone cocoa core-data nsmanagedobject xcode4

现在Xcode4已公开发售我正在将这个问题从Apple的秘密开发论坛中移除:

有人可以解释为什么以下过程中生成的代码与Xcode3中的代码不同?代码更好还是可能是错误?

我使用Core Data自定义托管类,这是我在Xcode3中遵循的过程:

  1. 转到模型编辑器
  2. 选择要为其生成源代码的实体
  3. 转到文件 - >新建>新文件
  4. 选择managedobject类(或其他任何类,我无法再打开xcode3进行验证)
  5. 选择您要生成的实体(已选中步骤2中先前选择的实体)
  6. 点击完成
  7. 现在,在Xcode4中,我认为这是如何做到的,但我不确定,因为它会生成不同的代码:

    1. 转到模特编辑器
    2. 选择实体
    3. 转到文件 - >新建>新文件
    4. 选择“NSManagedObject子类”
    5. 选择位置并创建。
    6. 由于多种原因,它产生的代码有所不同:

      1. 用于在实体中添加和删除集合成员的生成代码不再在@interface中声明,而是在@implementation中声明。这会导致代码检测无法检测到这些方法。
      2. 现在已完全定义了用于添加和删除对象的相同生成代码,不再使用CoreDataGeneratedAccessors自动生成
      3. 例如,Xcode3会在HEADER文件中生成此代码:

        @interface SampleEntity (CoreDataGeneratedAccessors)
        - (void)addChildObject:(Child *)value;
        - (void)removeChildObject:(Child *)value;
        - (void)addChild:(NSSet *)value;
        - (void)removeChild:(NSSet *)value;
        @end
        

        现在,Xcode4在IMPLEMENTATION文件中生成此代码:

        @implementation SampleEntity
        @dynamic children;
        - (void)addChildObject:(Child *)value {    
            NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
            [self willChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
            [[self primitiveValueForKey:@"children"] addObject:value];
            [self didChangeValueForKey:@"children" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
            [changedObjects release];
        }
        

        有人可以权衡为什么会有所不同吗? Xcode4代码感觉不喜欢这种生成NSManagedObject子类的新方法。

6 个答案:

答案 0 :(得分:11)

简答:不要使用Xcode的代码生成。使用发电机,享受更轻松的生活。

至于原因,很难说。我从来不喜欢Xcode生成Core Data子类的方式,也不会推荐它们。我们可以猜测为什么他们做了他们已经完成的事情,但是基于Xcode4和Core Data的其他问题,我会把它归结为“未准备好”或“未经过充分测试”。

如果您想继续使用Xcode代码生成器,请提交雷达文件。

答案 1 :(得分:1)

看起来Xcode4所做的就是明确@dynanmic指令隐含的内容。当您要求它生成特定属性(到剪贴板)的访问器时,生成的代码看起来与Xcode3生成的代码完全相同。

我不确定他们为什么决定这样做。可能他们认为如果他们只是给他们完整的基本访问器,它将使人们更容易创建自定义访问器。

对于某人来说,将MOGenerator强行插入Xcode4应该不会那么困难。提示提示。任何人?拜托了伙计们!任何人? Bueller?

叹息,看起来像我。

答案 2 :(得分:1)

Monogenerator不会使用Xcode 4进行插件,因此您可以使用runcript触发mogenerators命令行util:

mogenerator -m Resources/CoreData/XcodeProj.xcdatamodeld/XcodeProj1.xcdatamodel --base-class RootManagedObjectClass --template-path Resources/MoGenerator -O Sources/Classes

答案 3 :(得分:0)

我在大约一个月前发现了同样的问题,并在苹果的Xcode 4预览论坛上发布了这个问题。没有回复。为了让我的工作,我只是从.m文件中获取方法签名并在.h文件中创建了类别。基本上将生成的代码破解回XCode 3将如何完成它。我没有尝试使用Xcode 4的新版本。

答案 4 :(得分:0)

我使用你在XCode 4(最新的iOS4.3)中描述的旧XCode 3方式,它像以前一样工作,它为我生成的是:

    
#import <CoreData/CoreData.h>
@class JiraIssueType;
@class JiraPriority;
@class Customer;
@class JiraComment;
@class JiraComponent;
@class JiraUser;
@class Report;
@class Tag;

@interface JiraIssue :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * jiraId;
@property (nonatomic, retain) NSString * summary;
@property (nonatomic, retain) NSString * detailedDescription;
@property (nonatomic, retain) NSDate * createdDate;
@property (nonatomic, retain) NSDate * lastUpdatedDate;
@property (nonatomic, retain) NSString * key;
@property (nonatomic, retain) Report * report;
@property (nonatomic, retain) NSSet* comments;
@property (nonatomic, retain) JiraPriority * priority;
@property (nonatomic, retain) NSSet* components;
@property (nonatomic, retain) JiraIssueType * type;
@property (nonatomic, retain) Customer * customer;
@property (nonatomic, retain) NSSet* tags;
@property (nonatomic, retain) JiraUser * assignedTo;

@end


@interface JiraIssue (CoreDataGeneratedAccessors)
- (void)addCommentsObject:(JiraComment *)value;
- (void)removeCommentsObject:(JiraComment *)value;
- (void)addComments:(NSSet *)value;
- (void)removeComments:(NSSet *)value;

- (void)addComponentsObject:(JiraComponent *)value;
- (void)removeComponentsObject:(JiraComponent *)value;
- (void)addComponents:(NSSet *)value;
- (void)removeComponents:(NSSet *)value;

- (void)addTagsObject:(Tag *)value;
- (void)removeTagsObject:(Tag *)value;
- (void)addTags:(NSSet *)value;
- (void)removeTags:(NSSet *)value;

@end

答案 5 :(得分:0)

生成这些访问器非常方便,不确定为什么他们改变了它。

我使用此代码段作为替代方法:

- (void)add<#entity#>sObject:(<#entity#> *)value;
- (void)remove<#entity#>sObject:(<#entity#> *)value;
- (void)add<#entity#>s:(NSSet *)value;
- (void)remove<#entity#>s:(NSSet *)value;