我正在使用NSManagedObject的子类.实际上,它继承自一个继承自NSManagedObject的类的类(这应该不是问题,对吗?).
问题
在对对象的属性进行更改后,对象会记住其生命周期的更改,但更改永远不会保存到数据库中.
我怎么知道这个?
我知道这是因为:
没有任何东西写入数据库!
上下文
我正在使用自动生成的委托方法来创建商店协调器和上下文.然后我按照文档中的建议将上下文传递给它们的init方法中的视图控制器.这家商店是SQLite.
我能够成功地将对象插入数据库并读取它们.我甚至可以对新插入的对象进行属性更改并成功保存.当对象被拉回数据库时,我似乎无法更新对象属性.
通过来自另一个对象的关系从商店中获取对象.在更改其属性后,我调用上下文的save方法.但是,在这样做之前,我调用对象的isUpdated方法和上下文的hasChanges方法,并且都返回false.它们不应该返回true,因为我刚刚更改了对象的属性但没有保存上下文吗?
更多
如果我在保存上下文之前调用对象的committedChanges方法,但是,传入我已更改的属性的名称,我会返回属性的正确值.我不确定这意味着什么.我原以为这意味着对象的新属性值已成功保存,但很明显它们没有保存.
我知道结果对象是在上下文中注册的.如果我打电话
[[result managedObjectContext] refreshObject:result mergeChanges:YES];
Run Code Online (Sandbox Code Playgroud)
对象恢复为原始属性值.这意味着上下文存在,并且它是从中获取记录的相同上下文.这意味着新属性值永远不会写入数据库.
一些代码
这是我正在探讨所有这些事情的代码.我的代码中有其他地方我正在进行属性更改,但更改永远不会保存.
- (IBAction)statusControlChanged:(UISegmentedControl *)control {
WCAAssessmentResult *result = [self currentResult];
/* printing the existing property values */
if (![result.complete boolValue]) NSLog(@"result is in progress!");
else if ([result.passed boolValue]) NSLog(@"result is passed!");
else NSLog(@"result is not passed!");
/* changing the property values */
switch (control.selectedSegmentIndex) {
case 0:
NSLog(@"setting incomplete");
result.complete = [NSNumber numberWithBool:NO];
break; …Run Code Online (Sandbox Code Playgroud) 我的核心数据应用程序中有一个奇怪的问题.
我的应用程序中有三个实体,但今天我发现其中一个实体存在问题.我的有问题的实体被调用Invoice,它有许多属性,包括Products.它编码NSDrray的NSArray(通过默认的NSValueTransformer).
一切正常 - 我创建我的发票,客户,产品等.一切正常.
但是,当我从列表中选择发票然后尝试编辑其产品并单击"保存"按钮时,我的保存仅在我的应用程序终止之前有效.
问题只出在我的products阵列上 - 其余的(例如付款日期,客户等)保存.
我在做什么
我通过我的Invoice对象
NSManagedObject *inv = [self.fetchedResultsController objectAtIndexPath:indexPath];
invoiceEditor.invoice = inv;
Run Code Online (Sandbox Code Playgroud)
并保存我的数据(在我的InvoiceEditorVC中):
[self.invoice setValue:client forKey:@"Client"] // NSDictionary;
[self.invoice setValue:products forKey:@"Products"] // NSArray of NSDictionaries;
[self.invoice setValue:pmDate forKey:@"PaymentDate"] // NSDate;
// other attributes
NSManagedObjectContext *context = self.invoice.managedObjectContext;
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
Run Code Online (Sandbox Code Playgroud)
Everythings一直保存到终止:客户,产品,日期.但只有产品在终止后才会"重置".
任何人?
是否可以刷新Core Data托管对象的特定关系?我知道我可以刷新整个对象,但我想刷新一个特定的关系.我想我会通过使关系再次成为一个错误来实现这一点,但我似乎找不到任何可以实现这一目标的东西.你可以检查一个特定的关系是一个错误,但你不能强迫一个人是一个错误.
cocoa core-data objective-c nsmanagedobject nsmanagedobjectcontext
我有两个实例NSManagedObjectContext:一个在主线程中使用,另一个在后台线程中使用(通过NSOperation.)为了线程安全,这两个上下文只共享一个NSPersistentStoreCoordinator.
我遇到的问题是第一个上下文(在主线程上)中的挂起更改在-save执行之前不可用于第二个上下文.这是可以理解的,因为共享的持久性存储不会有副本NSManagedObjects由被跟踪-insertedObjects,-updatedObjects以及-deletedObjects被持久.
遗憾的是,这会给用户体验带来问题:任何未保存的更改都不会出现在后台线程中生成的(耗时)报告中.
我能想到的唯一解决方案是讨厌的:从第一个上下文中取出插入的,更新的和删除的对象,并将它们移植到第二个上下文的对象图上.数据集中有一些非常复杂的关系,所以我对这个方向犹豫不决.我希望有人在这里作为更好的解决方案.
core-data objective-c nsoperation nsmanagedobject nsmanagedobjectcontext
对于我在使用MagicalRecord数据导入时遇到的问题,我需要一些帮助.我的印象是MagicalRecord能够通过查看主键(relatedByAttribute)来处理关系映射而无需复制对象.
这是一个简单的JSON:
[
{
parentId: "<unique id>",
parentName : "<name>",
children : [
{
childId: "<unique id>",
childName: "<name>"
},
{
childId: "<unique id>",
childName: "<name>"
}
]
},
{ <another parent with children> }
]
Run Code Online (Sandbox Code Playgroud)
我有一个NSManagedObject Parent,它与NSManagedObject 有很多关系Child.关系的名字是children和我设置relatedByAttribute的Child,并Parent以childId和parentId分别.
当我解析JSON时,Parent它不会重复,它会正确检查主键并使用现有对象(如果存在).但是,Children每次我解析JSON时它都会复制对象.如果我Children单独解析(所以JSON只包含一个带有子词典的数组),它就没有问题正确映射数据并使用Children已存在于数据库中的现有对象.
我是否误解并对MagicalRecord如何映射关系抱有错误的期望?目前我已经设置了一个带有'importChildren:`的扩展类,我可以手动处理所有查找并相应地创建/导入对象.
谢谢!
我正在开发一个iOS应用程序,并有几个对象模型.现在我想将它们转换为核心数据管理对象,因此从对象创建实体和属性,而不是从模型生成对象的标准相反方式.完成此任务的最佳方法是什么?
我尝试从而NSManagedObject不是延伸NSObject,然后手动创建实体和属性,并为实体设置类名,但这不起作用:-(
谢谢
我在iOS应用程序中使用CoreData.在创建NSManagedObject类时,我大多数时候都会遇到问题.
这就是我做的:
.xcdatamodeld文件中创建一个实体.Editor->Create NSManagedObject Class创建.h和.m类的选项..h和.m类中,我创建了一些用于获取/保存对象的自定义方法.到现在为止还挺好.但是在将来如果我必须更改某些属性,我会重复步骤2和3.但是这次我在步骤4中编写的所有自定义代码都会自动删除.
所以我的问题是如何更新现有的类?而不是使用Editor->Create NSManagedObject Class删除所有自定义代码的选项.
任何帮助表示赞赏.
更新:
测试了两种方法(类别和Mogernator),看起来很好.但我选择了一种纯粹的Xcode方法.我不想承担由于XCode更新而导致将来可能破坏的任何第三方的风险,或者可能导致数据迁移问题.
感谢@Tom Harrington和@Valentin Shamardin指导我:)
我正在使用核心数据来保存vc1中的类别,并希望将列表属性添加到vc2中的列表中.我的数据模型是许多列表属性的一个类别.
我在vc1中添加了这样的类别:
func createNewCategory() {
var category: NSManagedObject! = NSEntityDescription.insertNewObjectForEntityForName("Category", inManagedObjectContext: self.context) as NSManagedObject
category.setValue(self.categoryTextField.text, forKey: "name")
var error: NSError? = nil
self.context.save(&error)
}
Run Code Online (Sandbox Code Playgroud)
在vc2中设置数据:
func setupCoreData() {
var appDelegate: AppDelegate = (UIApplication.sharedApplication()).delegate as AppDelegate
self.context = appDelegate.managedObjectContext!
var request: NSFetchRequest = NSFetchRequest(entityName: "Category")
if (self.context.executeFetchRequest(request, error: nil)) {
var error: NSError? = nil
self.listData = self.context.executeFetchRequest(request, error: &error)
self.managedObject = self.listData.objectAtIndex(0) as NSManagedObject
}
}
Run Code Online (Sandbox Code Playgroud)
它在最后一行崩溃:self.managedObject = ...说:
CoreData: error: Failed to call designated initializer on NSManagedObject …Run Code Online (Sandbox Code Playgroud) 使用镜像访问NSManagedObject的子类的内部结构时,将忽略所有托管变量.
public class Foo: NSManagedObject {
@NSManaged var bar: String?
}
var f: Foo = ...
// ... creating a Foo in a valid context ...
let mirror = Mirror(reflecting: f)
for c in mirror.children { // children count == 0
print("\(c.label!):\(c.value)") // never executed
}
Run Code Online (Sandbox Code Playgroud)
如何在NSManagedObjects上使用反射机制.
我从编码中休息了几个月然后回来发现CoreData与Xcode8/iOS10/macOS Sierra的变化.
我一直试图在Objective C中围绕新的NSManagedObject子类生成,但网上的内容很少.在我开始屠宰我的项目并完全搞砸了之前,我需要澄清一些事情,但首先,我发现的一些事情可能对其他人有用...
事情在哪里
自动生成的文件深埋在DerivedData文件夹中.查看USER-> Library-> Developer-> Xcode-> DerivedData-> ProjectName-lotsOfRandomLetters-> Build然后继续打开文件夹,直到找到DerivedSources-> CoreDataGenerated.
自动生成的文件不会出现在项目文件夹或导航器中,但如果一个Xcode中存在错误,则会显示源代码.
Xcode生成的东西
有三种codegen设置 - 手动/无,类定义和类别/扩展.
当实体codegen设置为manual/none(这是旧行为)时使用Editor-> Create创建NSmanagedObject子类NSManagedObject Subclass在项目中生成4个文件...
实体+ CoreDataClass.h和实体+ CoreDataClass.m和实体+ CoreDataProperties.h和实体+ CoreDataProperties.m
(以前的版本Xcode 7生成了Entity.h,Entity.m,Entity + CoreDataProperties.h和Entity + CoreDataProperties.m文件)
如果实体的codegen设置为Class Definition,Xcode会在派生数据文件夹中自动生成这4个相同的文件 - 而不是项目.然后这些文件会标记一条注释,告诉您不要更改它们.
如果实体codegen设置为Category/Extension,Xcode将生成2个文件.这些文件标有注释,告诉您不要更改它们.这些是...
Entity + CoreDataProperties.h和Entity + CoreDataProperties.m
这两个文件期望Entity.h文件在项目中,如果不存在则会在Xcode中显示错误.这是您有一次能够在Xcode中查看其中一个文件的来源.
什么是这些文件
+ CoreDataProperties文件看起来与生成以前版本的Xcode生成文件的文件相同,只有一个添加.它们包含实体/ NSmanagedObject的所有属性/属性以及处理具有一对多或多对多关系的实体的方法.新增加的是fetchRequest子类化NSmanageObject的新fetchRequest方法的方法.
问题
1)当您没有任何额外的属性/功能添加到NSManagedObject子类时,类定义现在是codegen的明显和最佳选择,因为它会自动为您更新文件(当您使用cmd -s保存项目时) ?
2)使用+ CoreDataClass命名文件遵循类的类别约定,这意味着应该有一个类作为扩展.
假设Entity + CoreDateClass .h/m文件是旧Entity.h/m文件的直接替换,我是否正确?并且它实际上不是一个类别,尽管文件名?
3)对于新的NSManagedObject子类,我应该导入Entity + CoreDataClass.h而不是Entity.h吗?
4)如果我想通过删除大部分NSManagedObject子类文件来整理我的项目,我只是删除Xcode中的文件并将实体codegen设置为Class Definition或...
当你尝试#import entity.h或者我必须经历并查找#import entity.h的每个引用并将它们更改为#import entity + CoreDataClass.h时,是否存在寻找实体+ CoreDataClass的魔法? ?
5)我是否正确地假设如果我想要一个NSManagedObject子类我要添加一个属性和一个方法,我应该将codegen设置为Category/Extension?
6)如果我选择Category/Extension我必须创建自己的NSmanagedObject子类文件,它只是entity.h而不是entity + CoreDataClass.h?
7)如果entity + …
core-data ×10
nsmanagedobject ×10
ios ×6
iphone ×4
objective-c ×4
swift ×2
cocoa ×1
cocoa-touch ×1
ios10 ×1
mirror ×1
model ×1
nsoperation ×1
reflection ×1
xcode8 ×1