自动代码中的无效重新声明生成 NSManagedObject 子类 Swift 3

invalid redeclaration in auto code generate NSManagedObject Subclass Swift 3

使用 Xcode 的 8.1 版。

在 .xcdatamodeld 文件中创建一个名为 "MapRegionObject" 的实体。

使用自动代码生成器,单击导航栏上的编辑器 -> 创建 NSManagedObject 子类...

获得两个文件:MapRegionObject+CoreDataClass.swift 和 MapRegionObject+CoreDataProperties

屏幕截图中显示的两个文件中的错误: 地图区域对象+CoreDataClass.swift

MapRegionObject+CoreDataProperties

请帮我解决这个问题,非常感谢!

我发现这个post对我的问题很有用。

What’s new in Core Data Swift 3.0

How to Use Core Data in iOS 10 (Swift 3)

在 Xcode 8.1 中,在使用自动代码生成器之前,您必须 select 数据模型中的实体:

然后转到“数据模型检查器”选项卡:

下"Codegen"select"Manual/Node"

之后您可以创建一个 NSManagedObject 子类而不会出错。


或者,如果您已经使用过 'Class Definition',您可以进入现有的 .xcdatamodeld 文件并将所有当前实体设置为 Codegen 下的 'Manual/None' .确保保存您的项目 (文件 -> 保存),删除现有的派生数据,清理项目,然后构建。为我解决了这个问题,而无需重新制作我的整个模型。

我发现整件事非常令人困惑。您确实需要了解 CoreData 中的新功能。基本上,默认设置是在一个名为 "DerivedData" 的地方为您自动生成 class 和扩展名,该位置埋在 ~/Library/Developer/Xcode/DerivedData 中,其中这些 classes 及其扩展在您的代码源之外存在。就个人而言,无法打开并查看它们对我来说很奇怪,但可以使用它。

基本上,如果您的 CoreData 模型中有一个名为 "AppSettings" 的实体,您可以直接使用它而无需自己生成代码。如果您想要项目中的代码,请将实体上的 Codegen 属性 设置为 Manual/None。然后执行您之前执行的操作:Editor->Create NSManagedObject classes,等等。这些文件将在您的项目中结束。

好消息是,如果您想进行自定义扩展,只需在您的项目中进行即可。 Xcode 将从项目目录之外的其他位置生成的文件与项目目录中的文件混合。

关闭项目并按照以下说明操作:

  1. 在 finder 中显示您的数据库 .xcdatamodeld 文件。
  2. 在 .xcdatamodeld 文件上右击 -> 显示包内容,如果(.xcdatamodel)再次在包中找到,再次右击并 'Show Package Contents'。你应该得到 'contents' 文件。
  3. 在文本编辑中打开 'contents'。
  4. Command-F (codeGenerationType="class") 并将所有匹配的字符串替换为空白字符串。

保存并打开 Xcode 项目 again.Everything 应该运行良好。

问题是您不再需要手动生成 NSManagedObjectModel 子类。 参考:https://forums.developer.apple.com/thread/48988

Xcode automatically generates classes or class extensions for the entities and properties in a Core Data data model. Automatic code generation is enabled and disabled on an entity by entity basis, and is enabled for all entities in new models using the Xcode 8 file format. This feature is available for any data model that has been upgraded to the Xcode 8 format. You specify whether Xcode generates Swift or Objective-C code for a data model using the data model’s file inspector. When automatic code generation is enabled for an entity, Xcode creates either a class or class extension for the entity as specified in the entity's inspector: the specified class name is used and the sources are placed in the project’s Derived Data. For both Swift and Objective-C, these classes are directly usable from the project’s code. For Objective-C, an additional header file is created for all generated entities in your model: The file name conforms to the naming convention 'DataModelName+CoreDataModel.h'.

除非您真的需要更改生成的属性,否则不要在这方面与 Xcode 作对,否则只会让您感到沮丧。

将 auto-generated class 视为应用程序中的任何其他 class。如果您需要向托管对象 class 添加功能,只需将 class 定义更改为扩展并扩展您的对象。

改变你的class:

class MyManagedObject : NSManagedObject { /* implementation*/ }

到分机:

extension MyManagedObject { /* implementation */ }

在Xcode 8.2.1 , Menu-Product-Clean,而且一切正常,很真实

1) 清理项目(cmd + shift + K)

2) 在 "data model inspector" 中,为每个创建的实体设置 Class 的属性,如下面的屏幕截图所示

3) 再次生成代码(Editor -> create NSManagedObject Subclasses)

在那之后一切都应该正常。

这不是答案。这只是对 selections

发生了什么的解释

确保你看到了 this moment for the Core Data Stanford course

以下是我自己写的文字记录(并非 100% 准确):

The default is class definition, if you choose this one. It will generate that subclass and it will just work. You'll be able to access your tweets as a class called Tweet. This sounds good. Btw if you do this it will NOT show up in your file navigator.

The one we choose the most often is the category/extension what this will do it will only generate an extension of the Tweet class. You have to actually write the tweet class itself. The extension will take care of making all the vars. Even when I switch to category/extension again I don't get that extension showing up in the navigator. It's kind of hidden from you.

And why do we like this one? Because a lot of times we want to add our own code. Like in a Tweet, imagine you want to add a static method that took data from Twitter and turned it into a tweet in the database. Where would we put code? Well a great place to put that code would be in the Tweet class...if there was such a thing...and the extension is going to handle all the var business for you.

If you did choose manual/none for codegen. meaning don't do any codegen, then you would be doing value/setValue(forKey:)...good luck with that You're code is going to be a mess. [ie there is no .propertyName = value ...you'd had to do setValue(value, forKey: propertyName)].


长话短说,我不确定为什么,但出于某种原因,如果您不 select 创建 NSManagedObject 子类 那么似乎仍然有效,但 没有 显示引擎盖下发生的事情。非常反直觉!


然后还可以观看 Core Data Stanford course:

的现场演示

Now we know we want to access all this stuff not using value/set(value:forKey:)...we want to have to subclasses of Users/Tweets. And we want to have vars [ dot notation] for all these relationships so we need that code to be generate. The way we do that we just select the entity... and we go down here to CodeGen. This says by default class definition. That means it's done it. It has generate a class called Tweet. and It's going to work with var and all relationships. That's not actually what we want. We want to select this one [Category/Extension]. Where only create an extension to Tweet and add the var stuff. That's because we want to write the class Tweet and put our own code in there. It's very common to write our own class. But you still want the var magic.