标签: nsmanagedobject

核心数据不会持续对数据库的属性更新

我正在使用NSManagedObject的子类.实际上,它继承自一个继承自NSManagedObject的类的类(这应该不是问题,对吗?).

问题

在对对象的属性进行更改后,对象会记住其生命周期的更改,但更改永远不会保存到数据库中.

我怎么知道这个?

我知道这是因为:

  • 当我重新启动应用程序时,我所做的更改将丢失.
  • 告诉上下文刷新对象 - 在我对对象进行了更改并告诉上下文保存之后 - 在我进行更改之前将对象的值设置回原始状态.
  • 在模拟器中运行应用程序时,我可以查看Finder中的sqlite数据库文件,当我尝试保存上下文时,它的修改日期不会更新.

没有任何东西写入数据库!

上下文

我正在使用自动生成的委托方法来创建商店协调器和上下文.然后我按照文档中的建议将上下文传递给它们的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)

iphone cocoa-touch core-data nsmanagedobject ios

5
推荐指数
1
解决办法
2839
查看次数

核心数据保存问题:无法更新可转换属性(NSArray)

我的核心数据应用程序中有一个奇怪的问题.

我的应用程序中有三个实体,但今天我发现其中一个实体存在问题.我的有问题的实体被调用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一直保存到终止:客户,产品,日期.但只有产品在终止后才会"重置".

任何人?

iphone core-data nsmanagedobject ios

5
推荐指数
1
解决办法
2484
查看次数

刷新核心数据关系

是否可以刷新Core Data托管对象的特定关系?我知道我可以刷新整个对象,但我想刷新一个特定的关系.我想我会通过使关系再次成为一个错误来实现这一点,但我似乎找不到任何可以实现这一目标的东西.你可以检查一个特定的关系是一个错误,但你不能强迫一个人是一个错误.

cocoa core-data objective-c nsmanagedobject nsmanagedobjectcontext

5
推荐指数
1
解决办法
1651
查看次数

在NSManagedObjectContexts与共享持久存储之间复制挂起的更改?

我有两个实例NSManagedObjectContext:一个在主线程中使用,另一个在后台线程中使用(通过NSOperation.)为了线程安全,这两个上下文只共享一个NSPersistentStoreCoordinator.

我遇到的问题是第一个上下文(在主线程上)中的挂起更改在-save执行之前不可用于第二个上下文.这是可以理解的,因为共享的持久性存储不会有副本NSManagedObjects由被跟踪-insertedObjects,-updatedObjects以及-deletedObjects被持久.

遗憾的是,这会给用户体验带来问题:任何未保存的更改都不会出现在后台线程中生成的(耗时)报告中.

我能想到的唯一解决方案是讨厌的:从第一个上下文中取出插入的,更新的和删除的对象,并将它们移植到第二个上下文的对象图上.数据集中有一些非常复杂的关系,所以我对这个方向犹豫不决.我希望有人在这里作为更好的解决方案.

core-data objective-c nsoperation nsmanagedobject nsmanagedobjectcontext

5
推荐指数
1
解决办法
1432
查看次数

尽管有主键,但MagicalRecord关系映射会复制对象

对于我在使用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和我设置relatedByAttributeChild,并ParentchildIdparentId分别.

当我解析JSON时,Parent它不会重复,它会正确检查主键并使用现有对象(如果存在).但是,Children每次我解析JSON时它都会复制对象.如果我Children单独解析(所以JSON只包含一个带有子词典的数组),它就没有问题正确映射数据并使用Children已存在于数据库中的现有对象.

我是否误解并对MagicalRecord如何映射关系抱有错误的期望?目前我已经设置了一个带有'importChildren:`的扩展类,我可以手动处理所有查找并相应地创建/导入对象.

谢谢!

core-data nsmanagedobject ios magicalrecord

5
推荐指数
1
解决办法
2334
查看次数

将现有对象模型转换为Core Data托管对象模型

我正在开发一个iOS应用程序,并有几个对象模型.现在我想将它们转换为核心数据管理对象,因此从对象创建实体和属性,而不是从模型生成对象的标准相反方式.完成此任务的最佳方法是什么?

我尝试从而NSManagedObject不是延伸NSObject,然后手动创建实体和属性,并为实体设置类名,但这不起作用:-(

谢谢

model core-data nsmanagedobject ios

5
推荐指数
1
解决办法
2590
查看次数

CoreData - 更新模型类而不是创建新模型

我在iOS应用程序中使用CoreData.在创建NSManagedObject类时,我大多数时候都会遇到问题.

这就是我做的:

  1. 我在.xcdatamodeld文件中创建一个实体.
  2. 创建属性和关系.
  3. 选择Editor->Create NSManagedObject Class创建.h.m类的选项.
  4. .h.m类中,我创建了一些用于获取/保存对象的自定义方法.

到现在为止还挺好.但是在将来如果我必须更改某些属性,我会重复步骤2和3.但是这次我在步骤4中编写的所有自定义代码都会自动删除.

所以我的问题是如何更新现有的类?而不是使用Editor->Create NSManagedObject Class删除所有自定义代码的选项.

任何帮助表示赞赏.

更新:

测试了两种方法(类别和Mogernator),看起来很好.但我选择了一种纯粹的Xcode方法.我不想承担由于XCode更新而导致将来可能破坏的任何第三方的风险,或者可能导致数据迁移问题.

感谢@Tom Harrington和@Valentin Shamardin指导我:)

iphone core-data objective-c nsmanagedobject ios

5
推荐指数
2
解决办法
7768
查看次数

Swift CoreData:错误:无法在NSManagedObject类'NSManagedObject'上调用指定的初始值设定项

我正在使用核心数据来保存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)

iphone core-data nsmanagedobject ios swift

5
推荐指数
1
解决办法
1万
查看次数

Swift:反映NSManagedObject的子类的属性

使用镜像访问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上使用反射机制.

reflection core-data mirror nsmanagedobject swift

5
推荐指数
1
解决办法
877
查看次数

更新Xcode 8核心数据NSManagedObject子类更改的Objective C项目的正确方法

我从编码中休息了几个月然后回来发现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 objective-c nsmanagedobject ios10 xcode8

5
推荐指数
1
解决办法
1030
查看次数