Xcode 8 为 iOS 10 生成损坏的 NSManagedObject 子类
Xcode 8 generates broken NSManagedObject subclasses for iOS 10
我最近将我的 iOS 应用程序项目更新为 iOS 10。现在我正在尝试更改我的应用程序的核心数据模型,但是 Xcode 生成的新 NSManagedObject 子类坏了。我也尝试修复子类手册,但这不起作用。
核心数据模型的最低工具版本设置为 Xcode 7.0,代码生成语言设置为 Swift。
这是 Xcode 生成的代码:
import Foundation
import CoreData
import
extension Group {
@nonobjc public class func fetchRequest() -> NSFetchRequest {
return NSFetchRequest(entityName: "Group");
}
@NSManaged public var name: String?
@NSManaged public var platform: NSNumber?
@NSManaged public var profiles: NSOrderedSet?
}
// MARK: Generated accessors for profiles
extension Group {
@objc(insertObject:inProfilesAtIndex:)
@NSManaged public func insertIntoProfiles(_ value: SavedProfile, at idx: Int)
@objc(removeObjectFromProfilesAtIndex:)
@NSManaged public func removeFromProfiles(at idx: Int)
@objc(insertProfiles:atIndexes:)
@NSManaged public func insertIntoProfiles(_ values: [SavedProfile], at indexes: NSIndexSet)
@objc(removeProfilesAtIndexes:)
@NSManaged public func removeFromProfiles(at indexes: NSIndexSet)
@objc(replaceObjectInProfilesAtIndex:withObject:)
@NSManaged public func replaceProfiles(at idx: Int, with value: SavedProfile)
@objc(replaceProfilesAtIndexes:withProfiles:)
@NSManaged public func replaceProfiles(at indexes: NSIndexSet, with values: [SavedProfile])
@objc(addProfilesObject:)
@NSManaged public func addToProfiles(_ value: SavedProfile)
@objc(removeProfilesObject:)
@NSManaged public func removeFromProfiles(_ value: SavedProfile)
@objc(addProfiles:)
@NSManaged public func addToProfiles(_ values: NSOrderedSet)
@objc(removeProfiles:)
@NSManaged public func removeFromProfiles(_ values: NSOrderedSet)
}
编辑:这些是 Xcode 给出的特定错误:
1. Group+CoreDataProperties.swift:13:1: Expected identifier in import declaration (the empty import)
2. Group+CoreDataProperties.swift:13:11: 'Group' is ambiguous for type lookup in this context
3. Group+CoreDataProperties.swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
4. Group+CoreDataProperties.swift:26:11: 'Group' is ambiguous for type lookup in this context
4. Group+CoreDataProperties.swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context
我发现这个 在某些方面很有帮助。
如果我按照大卫描述的方式生成代码。我只是得到了一些语法错误的代码,如果我修复了错误,一切都会像以前一样工作。没有丢失以“.”开头的文件没有了。
我必须纠正的语法错误是
- 不必要的进口
- 还有一些 public 属性在我的代码
中不打算成为 public
我终于开始工作了。这是我所做的。 (航班是我的实体之一)
我按如下方式设置 xcdatamodeld
然后实体为
然后我使用编辑器 -> 创建 NSManagedObject 子类
这会为我的航班实体创建两个文件
机票+CoreDataProperties.swift
机票+CoreDataClass.swift
我将 Flights+CoreDataClass.swift 重命名为 Flights.swift
Flights.swift 就是
import Foundation
import CoreData
@objc(Flights)
public class Flights: NSManagedObject {
}
航班+CoreDataProperties.swift是
import Foundation
import CoreData
extension Flights {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
return NSFetchRequest<Flights>(entityName: "Flights");
}
@NSManaged public var ...
}
这似乎适用于 me.I 无法让 Codegen 以任何其他方式工作,即使我尝试了那里的许多建议。
这也让我摸不着头脑,我把它作为一个辅助。不要忘记使用 FetchRequest 的新泛型版本,您可以做到这一点
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")
删除第 3 个 import
语句,因为它是空的。
注意:我不知道为什么会这样,但我猜这是Xcode8中的一个错误。只需删除它就可以正常工作。
我是 运行 最新的 Xcode 8.1 beta (8T47) 版本。
根据错误日志(见下文),创建了两个自动生成文件的副本。一个副本放在您的 Xcode 项目文件夹中(在 Xcode 左侧工具栏上您的目录中可见的那个),第二个副本在您的 DerivedData 文件夹中为您的项目创建:
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataProperties.swift
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataClass.swift
删除 Xcode 项目目录中的副本将解决所有问题,但事实证明毫无意义,因为您无法再编辑这些文件...
我不会说这是一个解决方案,而只是让项目构建的半途而废的方法。希望这个错误能尽快得到解决。
您需要做的是在执行创建 NSManagedObject 子类之前将 CodeGen 设置为 Category/Extension。
我相信您在生成 NSManagedObject 子类文件后遇到这些错误的原因可能与您在更改数据模型时选择的 Codegen 选项有关。
我不认为这是一个错误。至少在 Xcode 8.1 (8B62).
中没有
我遇到了类似的问题并通过将 Codegen 选项更改为 "Manual/None" 并将模块选项保留为 "Global Namespace" 来修复它。然后我生成了我的 NSManagedObject 子类文件。但是,根据您的情况,您甚至可能不需要生成 NSManagedObject 子类。
下面是基于我对 Apple 文档、Apple 开发者论坛和我自己的项目测试的审查,关于实体 Codegen 选项的更多详细信息。
选项 1:"Class Definition"
将此视为 "plug and play" 选项
使用模型编辑器创建实体和相关属性
您希望 Core Data 管理的内容。
不要使用 NSMangagedObject 子类生成器。所需的
文件由 Xcode 自动为您生成(但是它们确实
不会显示在您的项目导航器中)。
如果您确实生成了 NSManagedObject 文件,Apple 会告诉您
这些文件不应在 said 的 header 评论中编辑
文件。如果您确实需要编辑这些文件,那么这是个好兆头
您需要使用另一个 Codegen 选项。
保留实体的默认 Class 选项(模块 = 全局
命名空间和代码生成 = Class 定义)
如果你需要覆盖NSManagedObject的方法,你可以
使用 Class 选项下的名称创建扩展。
// Optional extension in Entity.swift
extension Entity {
// Override NSManagedObject methods
}
选项 2:"Manual/None"
与选项 1 类似,只是您可以查看和编辑
NSManagedObject 子类文件。
使用模型编辑器创建实体和相关属性
您希望 Core Data 管理的内容。
在使用 NSManagedObject 子类生成器之前,设置 Codgen
实体的 "Manual/None" 选项。模块选项应该是
全局命名空间。
在你add/remove/update一个属性之后,你有两个选择:(1)
手动更新为您生成的 NSManagedObject 文件
或者 (2) 再次使用 NSManagedObject 子类生成器(这将
仅更新 Entity+CoreDataProperties.swift 文件)。
同样,如果您需要重写 NSManagedObject 中的方法,您
可以创建一个扩展。扩展应该创建在
实体+CoreDataClass.swift 文件而不是
Entity+CoreDataProperties.swift 文件(该文件可能因
模型编辑器更改)。
// Optional extension in Entity+CoreDataClass.swift
extension Entity {
// Override NSManagedObject methods
}
选项 3:"Category/Extension"
如果您有不需要的自定义属性,请使用此选项
由核心数据管理。
使用模型编辑器创建实体和相关属性
您希望 Core Data 管理的内容。
确保 Module 选项设置为 Current Product Module 并且
Codegen 选项设置为 "Category/Extension".
使用您设置的属性创建您自己的 NSManagedObject 子类
将自行管理。
不要使用 NSMangagedObject 子类生成器。所需的
文件由 Xcode 自动为您生成(但是它们确实
不会显示在您的项目导航器中)。
// Subclass NSManagedObject in Entity.swift
class Entity: NSManagedObject {
// Self managed properties
}
// Optional extension in Entity.swift
extension Entity {
// Override NSManagedObject methods
}
我认为这是一个 xcode 问题,其中 xcode 为核心数据类别 class 生成了错误的语法。
我正在为一个实体 AgentDetails
创建一个 nsmanageobjectsubclass
这里 xcode 在 AgentDetails+CoreDataClass.h
和 AgentDetails+CoreDataClass.m
中创建了错误的代码结构。它们的代码结构如下:
和
所以它有重复的接口问题,因为 AgentDetails.h
有相同的接口。
现在要解决此问题,您必须更改 AgentDetails+CoreDataClass.h
中的代码
和AgentDetails+CoreDataClass.m
像这样:
尝试设置 CodeGen:Manual/None
模块:当前产品模块
当我遇到同样的问题时,它对我很有效。
Xcode 8.1 似乎在内部生成模型 Class。只需删除创建的 2 类,您仍然可以在代码中使用这些实体。
这是我收到的错误消息
<unknown>:0: error: filename "Recipe+CoreDataProperties.swift" used twice: '/Users/Rick/Desktop/Devslop/Rick Recipe/Recipe+CoreDataProperties.swift' and '/Users/Rick/Library/Developer/Xcode/DerivedData/Rick_Recipe-cctgjudvqobxlwetbcwmzrgxigwg/Build/Intermediates/Rick Recipe.build/Debug-iphonesimulator/Rick Recipe.build/DerivedSources/CoreDataGenerated/Rick_Recipe/Recipe+CoreDataProperties.swift'
<unknown>:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1
另外,如果您自己添加NSManagedObject子类,请不要忘记按照以下步骤操作:
转到 '.xcdatamodeld' -> 选择实体 -> 显示数据模型检查器 -> Codegen -> 选择 'Manual/None'
这对我有用。
在 Xcode 8.2.1,我做到了:(感谢 Daniel Chepenko)
但是Xcode 8.2.1会在生成的文件中添加一个愚蠢的.:
只需删除 . 即可 运行 正确。
如果您有旧版应用程序并且希望继续手动添加托管对象类
- 确保您的核心数据模型 codegen 设置为 Manual/None
- Select 你的核心数据模型文件
- 创建托管对象子类
在数据模型检查器 select 'Module' 下的当前产品模块和 'Codegen' 下的 Manual/None。 (这允许您编辑子类文件并在修改同一实体下的属性时重新生成 CoreDataProperties.swift。)
然后您可以在Editor 菜单下选择Create NSManagedObjectSubclass。 Xcode 将为您创建 2 个文件 YourEntity+CoreDataClass.swift 和 YourEntity+CoreDataProperties.swift。请注意,如果您没有最新的 Xcode (8.2.1),您在模型检查器中设置的任何 optional/nonoptional 属性都不会正确显示。你可以编辑
你的实体 +CoreDataProperties.swift 文件。
要解决此问题,请删除应用程序的派生数据。
然后将 Module 更改为 Current Product Module 并在 Codegen 到 Manual/None.
我有一个航班实体,数据模型检查器中的这些设置对我有用:
将名称设置为空(您会看到 "NSManagedObject" 的一些灰色文本)。默认将写为 "Flights" 只需将其删除。
模块中没有任何内容。"Global Namespace" 您将看到灰色的内容。
Codegen 到 Manual/None.
然后转到编辑器 -> 创建 NSManagedObject 子类以创建 swift 文件
将 Flights+CoreDataClass.swift 重命名为 Flights.swift
这是屏幕截图的 link(由于某些原因,imgur 拒绝了它:( ) https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing
我改名后如下:
来自:YourEntity+CoreDataClass.swift
收件人:YourEntity.swift
和
来自:YourEntity+CoreDataProperties.swift
致:你的实体CoreDataProperties.swift
然后就可以了。问题似乎是由“+”引起的。
您可以尝试这些步骤
- Select Xocde Project Navigator 中的 .xcdatamodeld 文件
- 在 Data Modul Inspector 中,确保 Codegen : Manual/None
- 然后编辑 -> 创建NSManagedObject子class
- 清理产品并重建
这是工作吗?如果没有
确保你们 class 与 Entities 的名称不同。您可以在 Build Phases -> Compile Sources 中找到这些 class。重命名 class 或重复的实体
或者
您可以运行在您的项目文件夹中使用此命令来获取更多错误信息
xcodebuild -verbose
遇到这个问题时我收到了这条消息
duplicate symbol _OBJC_CLASS_$_RandomList in:
xxxx/RandomList.o
xxxx/RandomList+CoreDataClass.o
RandomList.h和RandomList+CoreDataClass.h编译时符号相同
我想为什么Xcode没有警告你,但编译器会抛出错误
希望对您有所帮助
对我来说,我通过手动继承 NSManagedObject
创建了 CocoaTouch 类。我将模块设置为 Current Product Module,将 Codegen 设置为 Category/Extension,它运行良好。
我刚在我的模型中将一个 Person 实体添加到 Core Data 模板时遇到了问题。然后为此生成 NSManagedObject 子类,它不会编译,给我一个链接器错误。结果我应该将 Codegen 选项更改为 Manual/None 以使其工作(参见图片的右下部分)。
在我的特殊情况下,我已将 CoreData 添加到现有项目中,该项目已有一个与我的实体同名的模型 class。删除旧模型 class 解决了这个问题,因为它的类型与新的 CoreData 实体 class.
发生冲突
鉴于我可以看到很多解决问题的答案,所以我有点怀疑,但是
缺乏这里真正发生的事情背后的真正原因。
我偶然发现了同样的问题,通过快速研究我发现:
直到 Xcode7,Core Data 实体的默认行为是开发人员必须手动创建和维护相应 NSManagedObject 子类的更改。 (这可以并且仍然可以通过使用编辑器菜单选择 "Create NSManagedObject subclass.." 选项来完成)。
从 Xcode8 开始,Apple 在 Data Model Inspector 中包含了一项名为 Codegen 的新设置,用于管理和维护 NSManagedObject 子类.此设置的默认值是 "Class Definition",它告诉 Xcode 在编译时根据我们定义的实体生成 NSManagedObject 子类,并将它们放在派生数据文件夹中。
在项目中拥有我们的 NSManagedObject 子类 + Xcode 自动生成的子类让我们找到 "Multiple commands produce..." 编译时错误背后的真正原因,因为我们现在有重复的托管对象模型!!!
然后解决方案是使用一个或另一个,而不是两个!我个人更喜欢在项目中使用我的托管对象模型,因此我将此 "Codegen" 设置更改为 "Manual/None"。如果您不向模型添加逻辑,我敢打赌您可以选择删除项目的托管对象模型,并让 Xcode 根据上述设置的 "Class Definition" 值执行其操作。这才是处理这个问题的正确方法。
您可以在此处找到一篇详细解释所有这些的精彩文章:
https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041
我按照下面给出的例子解决了它
创建CurrentcyPair.xcdatamodeld
select CurrentcyPair.xcdatamodeld and select Default -> Entity (CurrencyPair) ,重命名 class 作为 (.ManagedCurrencyPair)
Select 实体并打开 Inspector。将数据模型的代码生成设置为 Manual/None
我最近将我的 iOS 应用程序项目更新为 iOS 10。现在我正在尝试更改我的应用程序的核心数据模型,但是 Xcode 生成的新 NSManagedObject 子类坏了。我也尝试修复子类手册,但这不起作用。
核心数据模型的最低工具版本设置为 Xcode 7.0,代码生成语言设置为 Swift。
这是 Xcode 生成的代码:
import Foundation
import CoreData
import
extension Group {
@nonobjc public class func fetchRequest() -> NSFetchRequest {
return NSFetchRequest(entityName: "Group");
}
@NSManaged public var name: String?
@NSManaged public var platform: NSNumber?
@NSManaged public var profiles: NSOrderedSet?
}
// MARK: Generated accessors for profiles
extension Group {
@objc(insertObject:inProfilesAtIndex:)
@NSManaged public func insertIntoProfiles(_ value: SavedProfile, at idx: Int)
@objc(removeObjectFromProfilesAtIndex:)
@NSManaged public func removeFromProfiles(at idx: Int)
@objc(insertProfiles:atIndexes:)
@NSManaged public func insertIntoProfiles(_ values: [SavedProfile], at indexes: NSIndexSet)
@objc(removeProfilesAtIndexes:)
@NSManaged public func removeFromProfiles(at indexes: NSIndexSet)
@objc(replaceObjectInProfilesAtIndex:withObject:)
@NSManaged public func replaceProfiles(at idx: Int, with value: SavedProfile)
@objc(replaceProfilesAtIndexes:withProfiles:)
@NSManaged public func replaceProfiles(at indexes: NSIndexSet, with values: [SavedProfile])
@objc(addProfilesObject:)
@NSManaged public func addToProfiles(_ value: SavedProfile)
@objc(removeProfilesObject:)
@NSManaged public func removeFromProfiles(_ value: SavedProfile)
@objc(addProfiles:)
@NSManaged public func addToProfiles(_ values: NSOrderedSet)
@objc(removeProfiles:)
@NSManaged public func removeFromProfiles(_ values: NSOrderedSet)
}
编辑:这些是 Xcode 给出的特定错误:
1. Group+CoreDataProperties.swift:13:1: Expected identifier in import declaration (the empty import)
2. Group+CoreDataProperties.swift:13:11: 'Group' is ambiguous for type lookup in this context
3. Group+CoreDataProperties.swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
4. Group+CoreDataProperties.swift:26:11: 'Group' is ambiguous for type lookup in this context
4. Group+CoreDataProperties.swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context
我发现这个
我必须纠正的语法错误是 - 不必要的进口 - 还有一些 public 属性在我的代码
中不打算成为 public我终于开始工作了。这是我所做的。 (航班是我的实体之一)
我按如下方式设置 xcdatamodeld
然后实体为
然后我使用编辑器 -> 创建 NSManagedObject 子类
这会为我的航班实体创建两个文件
机票+CoreDataProperties.swift
机票+CoreDataClass.swift
我将 Flights+CoreDataClass.swift 重命名为 Flights.swift
Flights.swift 就是
import Foundation
import CoreData
@objc(Flights)
public class Flights: NSManagedObject {
}
航班+CoreDataProperties.swift是
import Foundation
import CoreData
extension Flights {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
return NSFetchRequest<Flights>(entityName: "Flights");
}
@NSManaged public var ...
}
这似乎适用于 me.I 无法让 Codegen 以任何其他方式工作,即使我尝试了那里的许多建议。
这也让我摸不着头脑,我把它作为一个辅助。不要忘记使用 FetchRequest 的新泛型版本,您可以做到这一点
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")
删除第 3 个 import
语句,因为它是空的。
注意:我不知道为什么会这样,但我猜这是Xcode8中的一个错误。只需删除它就可以正常工作。
我是 运行 最新的 Xcode 8.1 beta (8T47) 版本。
根据错误日志(见下文),创建了两个自动生成文件的副本。一个副本放在您的 Xcode 项目文件夹中(在 Xcode 左侧工具栏上您的目录中可见的那个),第二个副本在您的 DerivedData 文件夹中为您的项目创建:
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataProperties.swift
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataClass.swift
删除 Xcode 项目目录中的副本将解决所有问题,但事实证明毫无意义,因为您无法再编辑这些文件...
我不会说这是一个解决方案,而只是让项目构建的半途而废的方法。希望这个错误能尽快得到解决。
您需要做的是在执行创建 NSManagedObject 子类之前将 CodeGen 设置为 Category/Extension。
我相信您在生成 NSManagedObject 子类文件后遇到这些错误的原因可能与您在更改数据模型时选择的 Codegen 选项有关。
我不认为这是一个错误。至少在 Xcode 8.1 (8B62).
中没有我遇到了类似的问题并通过将 Codegen 选项更改为 "Manual/None" 并将模块选项保留为 "Global Namespace" 来修复它。然后我生成了我的 NSManagedObject 子类文件。但是,根据您的情况,您甚至可能不需要生成 NSManagedObject 子类。
下面是基于我对 Apple 文档、Apple 开发者论坛和我自己的项目测试的审查,关于实体 Codegen 选项的更多详细信息。
选项 1:"Class Definition"
将此视为 "plug and play" 选项
使用模型编辑器创建实体和相关属性 您希望 Core Data 管理的内容。
不要使用 NSMangagedObject 子类生成器。所需的 文件由 Xcode 自动为您生成(但是它们确实 不会显示在您的项目导航器中)。
如果您确实生成了 NSManagedObject 文件,Apple 会告诉您 这些文件不应在 said 的 header 评论中编辑 文件。如果您确实需要编辑这些文件,那么这是个好兆头 您需要使用另一个 Codegen 选项。
保留实体的默认 Class 选项(模块 = 全局 命名空间和代码生成 = Class 定义)
如果你需要覆盖NSManagedObject的方法,你可以 使用 Class 选项下的名称创建扩展。
// Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }
选项 2:"Manual/None"
与选项 1 类似,只是您可以查看和编辑 NSManagedObject 子类文件。
使用模型编辑器创建实体和相关属性 您希望 Core Data 管理的内容。
在使用 NSManagedObject 子类生成器之前,设置 Codgen 实体的 "Manual/None" 选项。模块选项应该是 全局命名空间。
在你add/remove/update一个属性之后,你有两个选择:(1) 手动更新为您生成的 NSManagedObject 文件 或者 (2) 再次使用 NSManagedObject 子类生成器(这将 仅更新 Entity+CoreDataProperties.swift 文件)。
同样,如果您需要重写 NSManagedObject 中的方法,您 可以创建一个扩展。扩展应该创建在 实体+CoreDataClass.swift 文件而不是 Entity+CoreDataProperties.swift 文件(该文件可能因 模型编辑器更改)。
// Optional extension in Entity+CoreDataClass.swift extension Entity { // Override NSManagedObject methods }
选项 3:"Category/Extension"
如果您有不需要的自定义属性,请使用此选项 由核心数据管理。
使用模型编辑器创建实体和相关属性 您希望 Core Data 管理的内容。
确保 Module 选项设置为 Current Product Module 并且 Codegen 选项设置为 "Category/Extension".
使用您设置的属性创建您自己的 NSManagedObject 子类 将自行管理。
不要使用 NSMangagedObject 子类生成器。所需的 文件由 Xcode 自动为您生成(但是它们确实 不会显示在您的项目导航器中)。
// Subclass NSManagedObject in Entity.swift class Entity: NSManagedObject { // Self managed properties }
// Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }
我认为这是一个 xcode 问题,其中 xcode 为核心数据类别 class 生成了错误的语法。
我正在为一个实体 AgentDetails
创建一个 nsmanageobjectsubclass
这里 xcode 在 AgentDetails+CoreDataClass.h
和 AgentDetails+CoreDataClass.m
中创建了错误的代码结构。它们的代码结构如下:
和
所以它有重复的接口问题,因为 AgentDetails.h
有相同的接口。
现在要解决此问题,您必须更改 AgentDetails+CoreDataClass.h
和AgentDetails+CoreDataClass.m
像这样:
尝试设置 CodeGen:Manual/None 模块:当前产品模块
当我遇到同样的问题时,它对我很有效。
Xcode 8.1 似乎在内部生成模型 Class。只需删除创建的 2 类,您仍然可以在代码中使用这些实体。
这是我收到的错误消息
<unknown>:0: error: filename "Recipe+CoreDataProperties.swift" used twice: '/Users/Rick/Desktop/Devslop/Rick Recipe/Recipe+CoreDataProperties.swift' and '/Users/Rick/Library/Developer/Xcode/DerivedData/Rick_Recipe-cctgjudvqobxlwetbcwmzrgxigwg/Build/Intermediates/Rick Recipe.build/Debug-iphonesimulator/Rick Recipe.build/DerivedSources/CoreDataGenerated/Rick_Recipe/Recipe+CoreDataProperties.swift'
<unknown>:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1
另外,如果您自己添加NSManagedObject子类,请不要忘记按照以下步骤操作: 转到 '.xcdatamodeld' -> 选择实体 -> 显示数据模型检查器 -> Codegen -> 选择 'Manual/None'
这对我有用。
在 Xcode 8.2.1,我做到了:(感谢 Daniel Chepenko)
但是Xcode 8.2.1会在生成的文件中添加一个愚蠢的.:
只需删除 . 即可 运行 正确。
如果您有旧版应用程序并且希望继续手动添加托管对象类
- 确保您的核心数据模型 codegen 设置为 Manual/None
- Select 你的核心数据模型文件
- 创建托管对象子类
在数据模型检查器 select 'Module' 下的当前产品模块和 'Codegen' 下的 Manual/None。 (这允许您编辑子类文件并在修改同一实体下的属性时重新生成 CoreDataProperties.swift。)
然后您可以在Editor 菜单下选择Create NSManagedObjectSubclass。 Xcode 将为您创建 2 个文件 YourEntity+CoreDataClass.swift 和 YourEntity+CoreDataProperties.swift。请注意,如果您没有最新的 Xcode (8.2.1),您在模型检查器中设置的任何 optional/nonoptional 属性都不会正确显示。你可以编辑 你的实体 +CoreDataProperties.swift 文件。
要解决此问题,请删除应用程序的派生数据。
然后将 Module 更改为 Current Product Module 并在 Codegen 到 Manual/None.
我有一个航班实体,数据模型检查器中的这些设置对我有用:
将名称设置为空(您会看到 "NSManagedObject" 的一些灰色文本)。默认将写为 "Flights" 只需将其删除。
模块中没有任何内容。"Global Namespace" 您将看到灰色的内容。
Codegen 到 Manual/None.
然后转到编辑器 -> 创建 NSManagedObject 子类以创建 swift 文件
将 Flights+CoreDataClass.swift 重命名为 Flights.swift
这是屏幕截图的 link(由于某些原因,imgur 拒绝了它:( ) https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing
我改名后如下:
来自:YourEntity+CoreDataClass.swift 收件人:YourEntity.swift
和
来自:YourEntity+CoreDataProperties.swift 致:你的实体CoreDataProperties.swift
然后就可以了。问题似乎是由“+”引起的。
您可以尝试这些步骤
- Select Xocde Project Navigator 中的 .xcdatamodeld 文件
- 在 Data Modul Inspector 中,确保 Codegen : Manual/None
- 然后编辑 -> 创建NSManagedObject子class
- 清理产品并重建
这是工作吗?如果没有
确保你们 class 与 Entities 的名称不同。您可以在 Build Phases -> Compile Sources 中找到这些 class。重命名 class 或重复的实体
或者
您可以运行在您的项目文件夹中使用此命令来获取更多错误信息
xcodebuild -verbose
遇到这个问题时我收到了这条消息
duplicate symbol _OBJC_CLASS_$_RandomList in:
xxxx/RandomList.o
xxxx/RandomList+CoreDataClass.o
RandomList.h和RandomList+CoreDataClass.h编译时符号相同
我想为什么Xcode没有警告你,但编译器会抛出错误
希望对您有所帮助
对我来说,我通过手动继承 NSManagedObject
创建了 CocoaTouch 类。我将模块设置为 Current Product Module,将 Codegen 设置为 Category/Extension,它运行良好。
我刚在我的模型中将一个 Person 实体添加到 Core Data 模板时遇到了问题。然后为此生成 NSManagedObject 子类,它不会编译,给我一个链接器错误。结果我应该将 Codegen 选项更改为 Manual/None 以使其工作(参见图片的右下部分)。
在我的特殊情况下,我已将 CoreData 添加到现有项目中,该项目已有一个与我的实体同名的模型 class。删除旧模型 class 解决了这个问题,因为它的类型与新的 CoreData 实体 class.
发生冲突鉴于我可以看到很多解决问题的答案,所以我有点怀疑,但是 缺乏这里真正发生的事情背后的真正原因。
我偶然发现了同样的问题,通过快速研究我发现:
直到 Xcode7,Core Data 实体的默认行为是开发人员必须手动创建和维护相应 NSManagedObject 子类的更改。 (这可以并且仍然可以通过使用编辑器菜单选择 "Create NSManagedObject subclass.." 选项来完成)。
从 Xcode8 开始,Apple 在 Data Model Inspector 中包含了一项名为 Codegen 的新设置,用于管理和维护 NSManagedObject 子类.此设置的默认值是 "Class Definition",它告诉 Xcode 在编译时根据我们定义的实体生成 NSManagedObject 子类,并将它们放在派生数据文件夹中。
在项目中拥有我们的 NSManagedObject 子类 + Xcode 自动生成的子类让我们找到 "Multiple commands produce..." 编译时错误背后的真正原因,因为我们现在有重复的托管对象模型!!!
然后解决方案是使用一个或另一个,而不是两个!我个人更喜欢在项目中使用我的托管对象模型,因此我将此 "Codegen" 设置更改为 "Manual/None"。如果您不向模型添加逻辑,我敢打赌您可以选择删除项目的托管对象模型,并让 Xcode 根据上述设置的 "Class Definition" 值执行其操作。这才是处理这个问题的正确方法。
您可以在此处找到一篇详细解释所有这些的精彩文章:
https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041
我按照下面给出的例子解决了它
创建CurrentcyPair.xcdatamodeld
select CurrentcyPair.xcdatamodeld and select Default -> Entity (CurrencyPair) ,重命名 class 作为 (.ManagedCurrencyPair)
Select 实体并打开 Inspector。将数据模型的代码生成设置为 Manual/None