我最近将iOS应用程序项目更新到iOS 10.现在我尝试更改应用程序的核心数据模型,但Xcode生成的新NSManagedObject子类已损坏。我也尝试修复子类手册,但这不起作用。
Core Data Model的最低工具版本设置为Xcode 7.0,代码生成语言设置为Swift。
这是Xcode生成的代码:
$viewdefs ['<Module Name>'] =
array(
'<View Name>View' =>
array(
'templateMeta' =>
array(
...
'includes' =>
array(
0 =>
array(
'file' => 'path/to/your/script.js',
),
1 =>
array(
'file' => 'path/to/your/script.js',
),
),
...
),
...
),
...
);
编辑:这些是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)
}
答案 0 :(得分:105)
我终于让我上班了。这就是我做的。 (航班是我的实体之一)
我按如下方式设置xcdatamodeld
然后是实体
然后我用了编辑器 - &gt;创建NSManagedObject子类
这为我的航班实体创建了两个文件
航班+ CoreDataProperties.swift
航班+ CoreDataClass.swift
我将Flights + CoreDataClass.swift重命名为Flights.swift
Flights.swift只是
import Foundation
import CoreData
@objc(Flights)
public class Flights: NSManagedObject {
}
Flights + CoreDataProperties.swift
import Foundation
import CoreData
extension Flights {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
return NSFetchRequest<Flights>(entityName: "Flights");
}
@NSManaged public var ...
}
这似乎对我有用。我无法让Codegen以任何其他方式工作,即使我尝试过许多建议。
这也让我抓了一会儿,我把它作为助手添加。不要忘记使用新的Generics版本的FetchRequest,你可以做到这一点
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")
答案 1 :(得分:42)
我相信在生成NSManagedObject子类文件后遇到这些错误的原因可能与您的数据模型更改时选择的Codegen选项有关。
我不认为这是一个错误。至少在Xcode 8.1(8B62)中没有。
我遇到了类似的问题并通过将Codegen选项更改为&#34;手册/无&#34;来修复它。并将Module选项保留为&#34; Global Namespace&#34;。然后我生成了我的NSManagedObject子类文件。但是,根据您的具体情况,您甚至可能不需要生成NSManagedObject子类。
以下是我对Apple的文档,Apple开发人员论坛以及使用我自己的项目进行测试时对Codegen实体选项的更多详细信息。
选项1:&#34;课程定义&#34;
将此视为&#34;即插即用&#34;选项
使用模型编辑器创建实体和关联的属性 您希望Core Data管理。
不要使用NSMangagedObject子类生成器。所需 Xcode会自动为您生成文件(但是他们会这样做 没有出现在你的项目导航器中。)
如果您确实生成了NSManagedObject文件,Apple会告诉您 这些文件不应该在标题注释中编辑 文件。如果你确实需要编辑这些文件,那么这是个好兆头 你需要使用另一个Codegen选项。
保留实体的默认类选项(Module = Global 命名空间和Codegen =类定义)
如果需要覆盖NSManagedObject的方法,则可以 使用Class选项下的Name创建扩展名。
// Optional extension in Entity.swift
extension Entity {
// Override NSManagedObject methods
}
选项2:&#34;手动/无&#34;
与选项1类似,但您可以查看和编辑 NSManagedObject子类文件。
使用模型编辑器创建实体和关联的属性 您希望Core Data管理。
在使用NSManagedObject子类生成器之前,请设置Codgen 选项&#34;手动/无&#34;对于实体。 Module选项应该是 全球命名空间。
添加/删除/更新属性后,您有两种选择:(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:&#34;类别/扩展&#34;
如果您有不需要的自定义属性,请使用此选项 由Core Data管理。
使用模型编辑器创建实体和关联的属性 您希望Core Data管理。
确保“模块”选项设置为“当前产品模块”和“ Codegen选项设置为&#34;类别/扩展&#34;。
使用您的属性创建自己的NSManagedObject子类 将自我管理。
不要使用NSMangagedObject子类生成器。所需 Xcode会自动为您生成文件(但是他们会这样做 不会出现在项目导航器中。)
// Subclass NSManagedObject in Entity.swift
class Entity: NSManagedObject {
// Self managed properties
}
// Optional extension in Entity.swift
extension Entity {
// Override NSManagedObject methods
}
答案 2 :(得分:39)
答案 3 :(得分:17)
答案 4 :(得分:10)
您可以尝试以下步骤
那有用吗?如果不是
确保所有类与实体的名称不同。您可以在构建阶段 - &gt;中找到这些课程。 编译来源。重命名类或实体(如果它们重复)
或者
您可以在项目文件夹中运行此命令以获取更多错误信息
xcodebuild -verbose
我遇到此问题时收到此消息
重复符号_OBJC_CLASS _ $ _ RandomList in:
xxxx / RandomList.o
XXXX / RandomList + CoreDataClass.o
RandomList.h 和 RandomList + CoreDataClass.h 在编译时具有相同的符号
我认为为什么Xcode没有警告你,但编译器会抛出错误
希望这会对你有所帮助
答案 5 :(得分:7)
答案 6 :(得分:6)
删除第3个import
语句,因为它是空的。
注意:我不知道为什么会这样,但我想这是Xcode 8中的一个错误。只需将其删除即可。
答案 7 :(得分:5)
答案 8 :(得分:4)
我刚刚遇到一个问题,我只是将模型中的Person实体添加到Core Data模板中。然后为它生成NSManagedObject子类,它不会编译,给我一个链接器错误。事实证明我应该将Codegen选项更改为Manual / None以使其工作(请参见图片的右下角部分)。
答案 9 :(得分:3)
我认为这是一个xcode问题,xcode会为核心数据类别类生成错误的语法。
我正在为一个实体nsmanageobjectsubclass
创建AgentDetails
此处xcode在AgentDetails+CoreDataClass.h
和AgentDetails+CoreDataClass.m
中创建了错误的代码结构。它们的代码结构如下:
并且
因为AgentDetails.h
具有相同的界面,所以它存在重复的界面问题。
现在要修复此问题,您必须更改AgentDetails+CoreDataClass.h
和AgentDetails+CoreDataClass.m
是这样的:
答案 10 :(得分:2)
在数据模型检查器中,选择&#39;模块&#39;下的当前产品模块。 &#39; Codegen&#39;下的手动/无。 (这允许您在同一实体下修改属性时编辑子类文件并重新生成CoreDataProperties.swift。)
然后,您可以在“编辑器”菜单下选择“创建NSManagedObjectSubclass”。 Xcode将为您创建2个文件YourEntity + CoreDataClass.swift和YourEntity + CoreDataProperties.swift。请注意,如果您没有最新的Xcode(8.2.1),则您在模型检查器中设置的任何可选/非可选属性将无法正确显示。你可以编辑 YourEntity + CoreDataProperties.swift文件。
答案 11 :(得分:1)
Xcode 8.1似乎在内部生成Model 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
答案 12 :(得分:1)
此外,如果您自己添加NSManagedObject子类,请不要忘记按照以下步骤操作: 转到&#39; .xcdatamodeld&#39; - &GT;选择实体 - &gt;显示数据模型检查器 - &gt; Codegen - &gt;选择&#39;手动/无&#39;
这对我有用。
答案 13 :(得分:0)
我发现这个Post from David Atkinson在某种程度上有所帮助。 如果我按照David描述的方式生成代码。我只是得到一些语法错误的代码,如果我修复错误一切都像以前一样。没有丢失的文件以&#39;开头。&#39;更多。
我必须纠正的语法错误 - 不必要的进口 - 以及一些不打算在我的代码中公开的公共财产
答案 14 :(得分:0)
我正在运行最新的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项目目录中的副本将解决所有问题,但证明没有意义,因为您无法再编辑这些文件......
我不会说这是一个解决方案,而只是一种半实现方式来构建项目。希望这个bug很快就能解决。
答案 15 :(得分:0)
对我来说,我通过手动创建NSManagedObject
的子类来创建CocoaTouch类。我将模块设置为Current Product Module,将Codegen设置为Category / Extension,它运行良好。
答案 16 :(得分:0)
In my particular case, I had added CoreData to an existing project which already had a Model class by the same name as my entity. Deleting the old Model class fixed the problem, as its type was colliding with the new CoreData Entity class.
答案 17 :(得分:0)
考虑到可以解决问题的很多答案,我正在撒盐 缺乏真正的原因背后的真正原因。
我偶然发现了这个相同的问题,通过快速研究,我发现:
直到Xcode 7,Core Data实体的默认行为是开发人员必须手动创建和维护相应NSManagedObject子类的更改。 (这可以并且仍然可以通过使用编辑器菜单选择“创建NSManagedObject子类..”选项来实现)。
从Xcode 8开始,Apple在名为 Codegen 的数据模型检查器中包括了一个新设置,用于管理和维护NSManagedObject子类。此设置的默认值为“类定义”,它告诉Xcode在编译时根据定义的实体生成NSManagedObject子类,并将其放在派生数据文件夹中。
在项目中包含我们的NSManagedObject子类+ Xcode自动生成的子类使我们了解“多重命令产生...”编译时间错误的真正原因,因为我们现在已经复制了受管对象模型!!!
然后的解决方案是使用一个或另一个,而不是同时使用!我个人更喜欢将托管对象模型包含在项目中,因此我已将“ Codegen”设置更改为“ Manual / None”。如果您不向模型添加逻辑,那么您可以选择删除项目的托管对象模型,然后让Xcode根据提及的设置的“类定义”值来执行其操作。这是处理此问题的正确方法。
您可以在此处找到一篇精彩的文章,详细说明所有这些内容:
https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041
答案 18 :(得分:-1)
在执行Create NSManagedObject子类之前,您需要做的是将CodeGen设置为Category / Extension。
答案 19 :(得分:-1)
我有一个航班实体,数据模型检查器中的这些设置对我有用:
将名称设置为空(您将看到一些灰色的“NSManagedObject”文本)。默认值将写为“Flights”,只需删除它。
模块中没有任何内容。“全局命名空间”会显示为灰色。
Codegen to Manual / None。
然后转到编辑器 - &gt;创建NSManagedObject子类以创建swift文件
将Flights + CoreDataClass.swift重命名为Flights.swift
这是屏幕截图的链接(出于某种原因,imgur拒绝了它:()https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing
答案 20 :(得分:-1)
我用下面的例子解决了
创建 CurrentcyPair.xcdatamodeld
选择 CurrentcyPair.xcdatamodeld ,然后选择默认-> 实体(CurrencyPair),类(.ManagedCurrencyPair)
选择实体,然后打开检查器。将数据模型的代码生成设置为 Manual / None
答案 21 :(得分:-2)
重命名以下内容后:
发件人:YourEntity + CoreDataClass.swift 致:YourEntity.swift
和
发件人:YourEntity + CoreDataProperties.swift 收件人:YourEntityCoreDataProperties.swift
然后它的工作原理。它看起来像&#34; +&#34;引起了这个问题。