13

既然 Xcode4 是公开可用的,我将把这个问题移出 Apple 的秘密开发论坛:

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

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

  1. 转到模型编辑器
  2. 选择您要为其生成源代码的实体
  3. 转到文件->新建->新文件
  4. 选择 managedobject 类(或者不管它是什么,我不能再打开 xcode3 来验证)
  5. 选择您要生成的实体(之前在步骤 2 中选择的实体已勾选)
  6. 点击完成

现在,在 Xcode4 中,我认为这是如何做到的,但我不确定,因为它会生成不同的代码:

  1. 转到模型编辑器
  2. 选择实体
  3. 转到文件->新建->新建文件
  4. 选择“NSManagedObject 子类”
  5. 选择位置并创建。

由于多种原因,它生成的代码不同:

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

例如,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 code sense 不喜欢这种生成 NSManagedObject 子类的新方法。

4

6 回答 6

11

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

至于为什么,很难说。我从来都不喜欢 Xcode 生成 Core Data 子类的方式,因此不会推荐它们。我们可以猜测他们为什么做了他们所做的事情,但基于 Xcode4 和 Core Data 的其他问题,我会将其归为“未准备好”或“未完全测试”。

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

于 2011-03-10T01:21:43.477 回答
1

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

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

将 MOGenerator 硬塞到 Xcode4 中应该不难。提示提示。任何人?拜托了伙计们!任何人?布勒?

咳咳,好像是我。

于 2011-03-18T16:04:45.317 回答
1

Monogenerator 不使用 Xcode 4 插件,因此您可以使用触发 mogenerators 命令行工具的运行脚本:

mogenerator -m Resources/CoreData/XcodeProj.xcdatamodeld/XcodeProj1.xcdatamodel --base-class RootManagedObjectClass --template-path Resources/MoGenerator -O Sources/Classes
于 2011-03-20T09:42:34.150 回答
0

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

于 2011-03-10T01:25:28.703 回答
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
于 2011-03-21T23:04:10.087 回答
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;
于 2011-03-22T11:45:36.940 回答