强制使用已使用 NSUserDefaults 创建的实体

Posted

技术标签:

【中文标题】强制使用已使用 NSUserDefaults 创建的实体【英文标题】:Force use of an entity already create with NSUserDefaults 【发布时间】:2015-08-19 02:24:27 【问题描述】:

我正在尝试选择或按下一个或两个按钮,应用程序将创建一个与该社区相关的实体,从而根据选择显示以下屏幕。为了避免每次决定使用 NSUserDefaults 和实现时创建实体是这样的:

- (void)carregarEntidadeLojaComId:(NSString *)identificadorLoja keyNSUserDefault:(NSString *)key 
    if (![[NSUserDefaults standardUserDefaults] objectForKey:key]) 
        NSManagedObjectContext *contexto = [self managedObjectContext];

        NSArray *arrayLojas = [Utils carregarArrayPlist:identificadorLoja];
        NSArray *atributosComuns = @[@"titulo", @"subtitulo", @"telefone", @"endereco"];
        for (NSDictionary *dicionario in arrayLojas) 
            loja = [NSEntityDescription insertNewObjectForEntityForName:@"Loja" inManagedObjectContext:contexto];
            categoria = [NSEntityDescription insertNewObjectForEntityForName:@"Categoria" inManagedObjectContext:contexto];
            quadra = [NSEntityDescription insertNewObjectForEntityForName:@"Quadra" inManagedObjectContext:contexto];

            //Loop para atributos comuns
            for (NSString *atributo in atributosComuns) 
                [loja setValue:[dicionario objectForKey:atributo] forKey:atributo];
            

            [categoria setValue:[dicionario objectForKey:@"categoria"] forKey:@"nome"];
            [loja setValue:categoria forKey:@"categoria"];

            [quadra setValue:[dicionario objectForKey:@"quadra"] forKey:@"nome"];
            [loja setValue:quadra forKey:@"quadra"];
        
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
        [[NSUserDefaults standardUserDefaults] synchronize];
    

第一次转动,应用程序识别没有键并进入if语句,因此,创建实体。从您第二次使用该应用程序开始,它就不会进入 if 语句,但他不能使用已创建的实体,因此依赖于它们的屏幕没有实现。我的问题是如何强制应用程序使用用户第一次点击应用程序时创建的实体。

【问题讨论】:

根据您创建实体的代码而不将它们保存在任何地方。 @realtimez 我正在尝试从 plist 中读取,保存在 CoreData 上并导入回显示在表格上 【参考方案1】:

真的需要NSUserDefaults吗?

为什么不直接从 CoreData 本身查询实体,像这样:

- (void)carregarEntidadeLojaComId:(NSString *)identificadorLoja keyNSUserDefault:(NSString *)key 
    NSManagedObjectContext *contexto = [self managedObjectContext];

    NSFetchRequest *request = [NSFetchRequest new];
    request.entity = [NSEntityDescription entityForName:@"Loja"
                                 inManagedObjectContext:contexto];

    request.predicate = [NSPredicate predicateWithFormat:@"identificador = %@", identificadorLoja];

    NSError *error = nil;
    NSArray *fetchedObjects = [contexto executeFetchRequest:request error:&error];

    NSArray *lojas = nil;
    if ((error == nil) && [fetchedObjects count] > 0)
      lojas = fetchedObjects;

    if (!lojas) 
        NSArray *arrayLojas = [Utils carregarArrayPlist:identificadorLoja];
        NSArray *atributosComuns = @[@"titulo", @"subtitulo", @"telefone", @"endereco"];
        for (NSDictionary *dicionario in arrayLojas) 
            loja = [NSEntityDescription insertNewObjectForEntityForName:@"Loja" inManagedObjectContext:contexto];

            //Loop para atributos comuns
            for (NSString *atributo in atributosComuns) 
                [loja setValue:[dicionario objectForKey:atributo] forKey:atributo];
            

            [loja setValue:[self categoriaWithNome:[dicionario objectForKey:@"categoria"]
                                        inContexto:contexto]
                    forKey:@"categoria"];

            [loja setValue:[self quadraWithNome:[dicionario objectForKey:@"quadra"]
                                     inContexto:contexto]
                    forKey:@"quadra"];


            [loja setValue:identificadorLoja
                    forKey:@"identificador"]; 

        
     else 
      // do what you want with loja's, previously stored in CoreData

      for (NSManagedObject *entity in lojas)
        ...
    



- (NSManagedObject *) categoriaWithNome:(NSObject *)nome inContexto:(NSManagedObjectContext *)contexto 
  NSManagedObject *categoria = [NSEntityDescription insertNewObjectForEntityForName:@"Categoria" inManagedObjectContext:contexto];
  [categoria setValue:nome forKey:@"nome"];
  return categoria;


- (NSManagedObject *) quadraWithNome:(NSObject *)nome inContexto:(NSManagedObjectContext *)contexto 
  NSManagedObject *quadra = [NSEntityDescription insertNewObjectForEntityForName:@"Quadra" inManagedObjectContext:contexto];
  [quadra setValue:nome forKey:@"nome"];
  return quadra;
    

更新。

添加了predicate 以请求并删除了limit,因为每个identificadorLoja 似乎都有多个loja

【讨论】:

只是问但是.. 多次查询实体的性能如何? 过早的优化是万恶之源,你不知道吗? >:-) 顺便说一句,CoreData 是 really 快。在真正遇到某种瓶颈之前,不要费心缓存

以上是关于强制使用已使用 NSUserDefaults 创建的实体的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSKeyedArchiver 将 NSMutableArray 保存到 NSUserDefaults

如何使用 NSUserdefaults 为每个启动的对象创建一个密钥

NSUserDefaults的使用

NSUserDefaults存取失败

如何使用 NSUserDefaults 存储和加载 BOOL 数组或 int 数组? (IOS 7)

NSUserDefaults 不写入磁盘