当我在coredata中插入10k数据时花了这么多时间?

时间:2018-05-09 14:11:14

标签: ios swift core-data

在我的项目概念中,当用户打开应用程序时,我需要插入10k数据。我整合核心数据用于存储数据,但需要1到5分钟。 这是我的代码?

func inserChatMessage(_ message: String, chatId: String, onCompletion completionHandler:((_ message: ChatMessage) -> Void)?) {
    var objMessage: ChatMessage? = nil
    if let obj = ChatMessage.createEntity() {
        objMessage = obj
    }
    objMessage?.messageId = ""
    objMessage?.message = message
    objMessage?.chatId = chatId
    objMessage?.senderId = AIUser.current.userId
    objMessage?.createAt = Date()
    objMessage?.updateAt = Date()
    let cManager = CoreDataManager.sharedManager
    cManager.saveContext()

    if let completionHandler = completionHandler, let objMessage = objMessage {
        completionHandler(objMessage)
    }
}

1 个答案:

答案 0 :(得分:0)

Coredata不是线程安全的。根据您的要求,您需要在应用启动时保存大量数据。因此,如果您使用主线程保存这些数据,您的应用程序将被挂起。因此,在主线程上保存大量数据时,可以将这些数据保存在后台线程中。 Coredata通过提供父子环境概念来支持多线程概念。

我在我的一个项目中做了同样的工作并且工作正常。这里我附上了代码。

 func savePersonalMessagesOnBackGroundThread(arrMessages:NSArray,responseData:@escaping () -> Void)
{
    print(arrMessages)

    let temporaryChatContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType)
    temporaryChatContext.parent = self.managedObjectContext
    temporaryChatContext.perform({() -> Void in
        for i in 0..<arrMessages.count
        {
            let msgDic = arrMessages[i] as! NSDictionary
            _ = self.saveMessageInLocalDB(dictMessage: msgDic, managedObjectContext: temporaryChatContext, onBackground: true)

            if i == arrMessages.count - 1 {
                do {
                    try temporaryChatContext.save()
                    runOnMainThreadWithoutDeadlock {
                        DLog(message: "Thred \(Thread.isMainThread)")
                        if(self.managedObjectContext.hasChanges)
                        {
                            self.saveContext()
                            responseData()
                        }
                    }
                }
                catch {
                    print(error)
                }
            }
        }
    })
}

 func saveMessageInLocalDB(dictMessage:NSDictionary, managedObjectContext:NSManagedObjectContext,onBackground:Bool) -> Chat
{
    var chatObj : Chat! = Chat()
    var receiveId: Int32!
    var flag:Bool = false
    print(dictMessage)

   // let predicate = NSPredicate(format:"uniqueId == %@ and senderId = %d and receiverId = %d","\(dictMessage.value(forKey:keyuniqueId)!)",Int32(dictMessage.value(forKey:keysenderId) as! Int64),Int32(dictMessage.value(forKey:keyreceiverId) as! Int64))
     let predicate = NSPredicate(format:"uniqueId == %@","\(dictMessage.value(forKey:keyuniqueId)!)")
    let objContext = managedObjectContext
    let fetchRequest = NSFetchRequest<Chat>(entityName: ENTITY_CHAT)
    let disentity: NSEntityDescription = NSEntityDescription.entity(forEntityName: ENTITY_CHAT, in: objContext)!
    fetchRequest.predicate = predicate
    fetchRequest.entity = disentity

    do{
        let results = try  managedObjectContext.fetch(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) as! [Chat]
        if(results.count > 0)
        {
            chatObj = results[0]
            chatObj.messageId = Int32(dictMessage.value(forKey:keymessageId) as! Int64)
            chatObj.dateOnly = dictMessage.value(forKey:keydateOnly) as! String?
        }
        else{

                //receiveId = Int32(dictMessage.value(forKey:keyreceiverId) as! Int64)
                //self.createNewChatObject(dictMessage: dictMessage, receiverId: receiveId, managedObjectContext: managedObjectContext)
                chatObj = NSEntityDescription.insertNewObject(forEntityName:ENTITY_CHAT,into: managedObjectContext) as? Chat

                if dictMessage[keymessageId] != nil {
                    chatObj.messageId = dictMessage.value(forKey:keymessageId) as! Int32
                }

                if(chatObj.message?.length != 0)
                {
                    chatObj.message = dictMessage.value(forKey:keychatMessage) as? String
                }

                chatObj.messageType = Int32(dictMessage.value(forKey:keymessageType) as! Int64)
                chatObj.senderId = Int32(dictMessage.value(forKey:keysenderId) as! Int64)
                if(chatObj.senderId != Int32((APP_DELEGATE.loggedInUser?.id!)!))
                {
                    let contactObj = self.getContactByContactId(contactId: Int32(dictMessage.value(forKey:keysenderId) as! Int64))
                    if(contactObj == nil)
                    {
                       _ = self.saveUnknownUserASContact(msgDict: dictMessage as! Dictionary<String, Any>)
                    }
                }
                chatObj.receiverId = Int32(dictMessage.value(forKey:keyreceiverId) as! Int64)
                chatObj.uniqueId = dictMessage.value(forKey:keyuniqueId) as? String
                chatObj.mediaName = dictMessage.value(forKey:keymediaName) as? String

                print(NSDate())
                if dictMessage[keycreatedDate] != nil {
                    let utcDate : NSDate =  DateFormater.getUTCDateFromUTCString(givenDate: dictMessage.value(forKey:keycreatedDate) as! String)

                    chatObj.createdDate = utcDate
                    chatObj.updatedDate =  utcDate
                }
                else
                {
                    chatObj.createdDate = NSDate()
                    chatObj.updatedDate = NSDate()
                }

                if(chatObj.senderId == Int32((APP_DELEGATE.loggedInUser?.id)!))
                {
                    chatObj.chatUser = chatObj.receiverId
                }
                else
                {
                    chatObj.chatUser = chatObj.senderId
                }

                if dictMessage[keystatus] != nil {
                    chatObj.status =  Bool((dictMessage.value(forKey:keystatus) as! Int64) as NSNumber)
                }

                switch Int(chatObj.messageType)
                {
                case MSG_TYPE.MSG_Text.rawValue:
                    chatObj.cellType = (chatObj.senderId != Int32((APP_DELEGATE.loggedInUser?.id!)!) ? Int32(CELL_TYPE.CELL_TEXT_RECEIVER.rawValue) : Int32(CELL_TYPE.CELL_TEXT_SENDER.rawValue))

                case MSG_TYPE.MSG_Image.rawValue:
                    chatObj.cellType = (chatObj.senderId != Int32((APP_DELEGATE.loggedInUser?.id!)!) ? Int32(CELL_TYPE.CELL_IMAGE_RECEIVER.rawValue) : Int32(CELL_TYPE.CELL_IMAGE_SENDER.rawValue))
                    self.saveMedia(chatObj: chatObj)

                default :
                    // chatObj.cellType = Int32(CELL_TYPE.CELL_LOAD_MORE.rawValue)
                    break
                }
            }


            //   deviceMake = 1;
            if(!onBackground)
            {
                self.saveContext()
            }
        }
    catch
    {

    }

    return chatObj

}