如何在Core Data中更新现有对象?

63

当我插入新对象时,我会使用以下代码:

NSManagedObjectContext *context = [appDelegate managedObjectContext];

Favorits *favorits = [NSEntityDescription insertNewObjectForEntityForName:@"Favorits" inManagedObjectContext:context];

favorits.title = @"Some title";

NSError *error;                    
if (![context save:&error]) {
    NSLog(@"Whoops");
}

如何在Core Data中更新现有对象?

5个回答

135
更新很简单,就像创建一个新的一样。
要更新特定对象,您需要设置一个NSFetchRequest。这个类相当于SQL语言中的SELECT语句。
以下是一个简单的示例:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Favorits" inManagedObjectContext:moc]];

NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];

// error handling code

数组 results 包含了 sqlite 文件中的所有托管对象。如果你想获取特定的对象(或多个对象),你需要使用一个谓词来进行请求。例如:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title == %@", @"Some Title"];
[request setPredicate:predicate]; 

在这种情况下,results 包含了标题等于 Some Title 的对象。设置谓词相当于在 SQL 语句中使用 WHERE 子句。
如需进一步了解,请阅读 Core Data 编程指南和 NSFecthRequest 类参考文档。 希望能帮到您。 编辑(可用于更新的代码片段)
// maybe some check before, to be sure results is not empty
Favorits* favoritsGrabbed = [results objectAtIndex:0];    
favoritsGrabbed.title = @"My Title";

// save here the context

如果您没有使用NSManagedObject的子类。

// maybe some check before, to be sure results is not empty
NSManagedObject* favoritsGrabbed = [results objectAtIndex:0];
[favoritsGrabbed setValue:@"My title" forKey:@"title"];

// save here the context

无论哪种情况,如果在上下文中执行save操作,数据都将被更新。


@CroiOS 我的例子非常简单,没有考虑内存管理。 - Lorenzo B
谢谢。您能否更新您的帖子并添加更新此对象的示例代码,我已经获取了它。我在这里:Favorits *myObject = [array objectAtIndex:0];..接下来是什么? - iWizard
@CroiOS 我添加了一个编辑。正如我之前所评论的,代码非常简单,但在修改托管对象之前需要进行一些检查。这只是为了指导您在检索后修改托管对象。顺便说一下,请检查代码,因为我是手写的。希望能对您有所帮助。 - Lorenzo B
3
你需要创建一个请求,修改你感兴趣的属性,然后保存。 - Lorenzo B
1
谢谢您指出我根本不需要子类化NSManagedObject就可以使其工作! - ctietze
显示剩余2条评论

11
你需要从上下文中 获取 对象,更改所需的属性,然后像你的示例一样保存上下文。

1
@CroiOS 你可以像最初设置属性一样来更改它们,保存时也是同样的方式。 - sosborn

7

我希望这能对您有所帮助,因为它对我很有效。

 NSMutableArray *results = [[NSMutableArray alloc]init];
int flag=0;
NSPredicate *pred;
if (self.txtCourseNo.text.length > 0) {
    pred =  [NSPredicate predicateWithFormat:@"courseno CONTAINS[cd] %@", self.txtCourseNo.text];
    flag=1;
} else {
    flag=0;
    NSLog(@"Enter Corect Course number");
}

if (flag == 1) {

    NSLog(@"predicate: %@",pred);
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"Course"];
    [fetchRequest setPredicate:pred];
    results = [[self.context executeFetchRequest:fetchRequest error:nil] mutableCopy];


    if (results.count > 0) {
        NSManagedObject* favoritsGrabbed = [results objectAtIndex:0];
        [favoritsGrabbed setValue:self.txtCourseName.text forKey:@"coursename"];
        [self.context save:nil];
        [self showData];
    } else {
        NSLog(@"Enter Corect Course number");
    }



}

4
如果你是一位Swift程序员,这会对你有所帮助:
如果你想删除一个NSManagedObject
在我的情况下,ID是实体“STUDENT”中的唯一属性。
/** for deleting items */

func delete(identifier: String) {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "STUDENT")
    let predicate = NSPredicate(format: "ID = '\(identifier)'")
    fetchRequest.predicate = predicate
    do
    {
        let object = try context.fetch(fetchRequest)
        if object.count == 1
        {
            let objectDelete = object.first as! NSManagedObject

                 context.delete(objectDelete)
        }
    }
    catch
    {
        print(error)
    }
} 

如果您想更新一个NSManagedObject:

/** for updating items */
func update(identifier: String,name:String) {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "STUDENT")
    let predicate = NSPredicate(format: "ID = '\(identifier)'")
    fetchRequest.predicate = predicate
    do
    {
        let object = try context.fetch(fetchRequest)
        if object.count == 1
        {
            let objectUpdate = object.first as! NSManagedObject
            objectUpdate.setValue(name, forKey: "name")
            do{
                try context.save()
            }
            catch
            {
                print(error)
            }
        }
    }
    catch
    {
        print(error)
    }
}

1

我在Objective-C中看到了一个有帮助的答案。现在我为Swift用户提供一个答案 -

guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
    return
}
let updateCont = appDelegate?.persistentContainer.viewContext
let pred = NSPredicate(format: "your_Attribute_Name = %@", argumentArray : [your_Arguments])
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "your_Entity_Name")
request.predicate = pred

do {
    let resul = try updateCont?.fetch(request) as? [NSManagedObject]
    let m = resul?.first
    m?.setValue(txtName.text, forKey: "your_Attribute_Name_Whose_Value_Should_Update")
    try? updateCont?.save()
} catch let err as NSError {
    print(err)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接