ios - 如何使用 NSManagedObjectContext 进行条件请求?

标签 ios objective-c nsmanagedobjectcontext nsfetchrequest

我是 NSManagedObjectContext 的新手。我在我的应用程序中创建了一个实体 Link,其中包含一个 NSString *url

在我的应用程序的某个时刻,我需要在我的基础中插入一个新的 Link,所以我只需这样做:

Link *link = [NSEntityDescription 
                         insertNewObjectForEntityForName:@"Link" 
                         inManagedObjectContext:self.managedObjectContext];
link.url = myUrl;

但在执行此操作之前,我想检查我的库中是否还没有具有相同 url 的链接。我不知道该怎么做...我应该怎么做?

编辑:从我在网上找到的工具中使用此方法的基础检索数据:

// Fetch objects with a predicate
+(NSMutableArray *)searchObjectsForEntity:(NSString*)entityName withPredicate:(NSPredicate *)predicate andSortKey:(NSString*)sortKey andSortAscending:(BOOL)sortAscending andContext:(NSManagedObjectContext *)managedObjectContext
{
    // Create fetch request
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];

    // If a predicate was specified then use it in the request
    if (predicate != nil)
        [request setPredicate:predicate];

    // If a sort key was passed then use it in the request
    if (sortKey != nil) {
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:sortAscending];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [request setSortDescriptors:sortDescriptors];
    }

    // Execute the fetch request
    NSError *error = nil;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];

    // If the returned array was nil then there was an error
    if (mutableFetchResults == nil)
        NSLog(@"Couldn't get objects for entity %@", entityName);

    // Return the results
    return mutableFetchResults;
}

我想知道如何使用它。

感谢您的帮助。

最佳答案

您提供的方法只搜索与 NSManagedObjectContext 中的属性匹配的 NSManagedObject,如果存在,则返回它。

但是,您需要实现的是所谓的“查找或创建”模式,Core Data 编程指南中对此进行了讨论。基本上,您搜索符合特定条件的对象,如果存在则返回该对象。如果该对象不存在,则创建它。

Core Data Programming Guide

例如

+ (NSString *)entityName
{
    return NSStringFromClass([Link class]);
}

+ (instancetype)findUsingPredicate:(NSPredicate *)predicate withContext:(NSManagedObjectContext *)context
{
    Link * entity;

    // Setup the fetchRequest
    NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[[self class] entityName]];
    fetchRequest.predicate = predicate;

    // Credit: @Martin R
    [fetchRequest setFetchLimit:1];

    // Execute the fetchRequest
    NSError *error = nil;
    NSArray * matchingLinks = [context executeFetchRequest:fetchRequest error:&error];

    // MatchingLinks will only return nil if an error has occurred otherwise it will return 0
    if (!matchingLinks)
    {
        // handle error
        // Core data returns nil if an error occured
        NSLog(@"%s %@", __PRETTY_FUNCTION__, [error description]);
    }
    else if ([matchingLinks count] <= 0)
    {
        // if the count <= 0, there were no matches

        NSLog(@"%s Not found", __PRETTY_FUNCTION__);

    } else {

        // A link with a url that matches the url in the dictionary was found.
        NSLog(@"%s Found", __PRETTY_FUNCTION__);

        entity = [matchingLinks lastObject];
    }

    return entity;
}

+ (instancetype)findUsingPredicate:(NSPredicate *)predicate orCreateWithContext:(NSManagedObjectContext *)context
{
    Link * entity = [[self class] findUsingPredicate:predicate withContext:context];

    if (!entity) {
        entity = [[self class] createWithContext:context];
    }

    return entity;
}

+ (isntancetype)createWithContext:(NSManagedObjectContext *)context
{
    return [[self class] alloc] initWithContext:context];
}

- (instancetype)initWithContext:(NSManagedObjectContext *)context
{
    Link * entity = [NSEntityDescription insertNewObjectForEntityForName:[[self class] entityName] inManagedObjectContext:context];

    return entity;
}

用例:

NSString * url = @"http://www.mylink.com";
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"url = %@", url];
Link * link = [Link findUsingPredicate:predicate orCreateWithContext:self.managedObjectContext];
link.url = url;

关于ios - 如何使用 NSManagedObjectContext 进行条件请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19819791/

相关文章:

ios - 在我的应用程序开始时使用 6 个图像为应用程序创建入门教程 - 停留在实际创建图像上

objective-c - 更新 Cocos2d 1.0.1 的方法和类

iphone - textFieldDidBeginEditing - 不工作

ios - 尝试将 ManagedObjectContext 从 GameAppDelegate 传递到嵌入在 NavigationController 中的 View

swift - Swift 中的错误 "Trailing closure passed to parameter of type ' NSManagedObjectContext' 不接受闭包

ios - 什么时候从 2 个不同的类中获取 obtainPermanentIDsForObjects :error: ever needed??

iphone - 带有分组单元格的普通 UITableView

ios - NSError 没有可见界面 iOS 8.1

objective-c - cocos2D&lt;不起作用

ios - 在构建混合和匹配的 Obj C/Swift 项目之前总是必须清理