可視化建模--CoreData

想要實(shí)現(xiàn)可視化建模,需要New File,選擇Core Data>Data Model,建立模型,模型名稱,最好與工程名相同

一、對象與實(shí)體的映射

對象(Object)與數(shù)據(jù)庫的實(shí)體(Entity)對應(yīng)
對象與實(shí)體都擁有屬性(Attribute)
CoreData.png
@圖片是二進(jìn)制文件

二、創(chuàng)建托管對象

一旦使用CoreData,必須要把對象置于CoreData框架托管

在當(dāng)前創(chuàng)建的可視化模型中,在其屬性的Class > Name,加上MO,這樣,在Build工程后,會自動創(chuàng)建name+MO的托管對象 的類定義,但文件是不可見的

//由于此時 不需要再沒次都用代碼寫數(shù)據(jù),數(shù)據(jù)源可以留空
var areas : [AreaMO] = []

三、保存數(shù)據(jù)的步驟

iOS10中大幅度簡化了Core Data用法,保存數(shù)據(jù)只需要2步
3.1、類似一下代碼,創(chuàng)建一個AreaMO實(shí)例,設(shè)置屬性
var area: AreaMO!
3.2、調(diào)用AppDelegate中的saveContext方法
@IBAction func saveTap(_ sender: UIBarButtonItem) {
        
        //獲取appDelegate
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        
        //Core Data持久化容器中的context
        area = AreaMO(context: appDelegate.persistentContainer.viewContext)
        area.name = tfName.text
        area.province = tfProvince.text
        area.part = tfPart.text
        area.visited = isVisited
        
        //圖片轉(zhuǎn)為 JPG格式
        if let imageData = UIImageJPEGRepresentation(coverImageView.image!, 0.7) {
            area.thumbImage = NSData(data: imageData) as Data
        }
        
        //保存并返回首頁
        print("正在保存")
        appDelegate.saveContext()
        performSegue(withIdentifier: "unwindToHomeList", sender: self)
    }

四、讀取保存的數(shù)據(jù)

// MARK: - 寫一個獲取所有Area Entity下數(shù)據(jù)的方法
    func fetchAllData() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        
        //do-try-catch錯誤處理
        do {
            //AreaMO.fetchRequest() 獲取AreaMO此Entity的所有條目
            
            areas = try appDelegate.persistentContainer.viewContext.fetch(AreaMO.fetchRequest())
        } catch  {
            print(error)
        }
        
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        
        //放在viewDidAppear里執(zhí)行
        fetchAllData()
        tableView.reloadData()

    }

五、高效刷新:

沒次全部更新tableView,性能上是不可接受的
能達(dá)到以下效果再好不過

加一條,出現(xiàn)一條
刪一條,少一條

NSFetchedResultsController
可把單元格內(nèi)容與數(shù)據(jù)進(jìn)行綁定,響應(yīng)數(shù)據(jù)變化
@第一步:
import CoreData
@第二步:
遵從NSFetchedResultsControllerDelegate協(xié)議
此協(xié)議提供數(shù)據(jù)變化時的通知及代理的方法
@第三步:
定義一個NSFetchedResultsController變量
var fc : NSFetchedResultsController<AreaMO>!
@主體代碼:
func fetchAllData2() {
        //請求結(jié)果是AreaMO
        let request : NSFetchRequest<AreaMO> = AreaMO.fetchRequest()
        //NSSortDescriptor指定請求結(jié)果如何排序
        let sd = NSSortDescriptor(key: "name", ascending: true)
        request.sortDescriptors = [sd]
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        //NSFetchedResultsController初始化后,指定代理
        fc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        fc.delegate = self
        
        //執(zhí)行查詢,將結(jié)果保存到數(shù)組中
        do {
            try fc.performFetch()
            if let objects = fc.fetchedObjects {
                areas = objects
                
            }
        } catch {
            print(error)
        }
        //如果執(zhí)行,會顯示上一次保存的數(shù)據(jù),但新增數(shù)據(jù)后,表格不會更新
        
    }

六、代理方法

當(dāng)數(shù)據(jù)內(nèi)容發(fā)生變化時,NSFetchedResultsControllerDelegate協(xié)議的以下方法會被調(diào)用:

//當(dāng)控制器開始處理內(nèi)容變化時
    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
       tableView.beginUpdates()
    }
    //內(nèi)容發(fā)生變更時
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
       
        switch type {
        case .delete:
            tableView.deleteRows(at: [indexPath!], with: .automatic)
        case .insert:
            tableView.insertRows(at: [newIndexPath!], with: .automatic)
        case .update:
            tableView.reloadRows(at: [indexPath!], with: .automatic)
        default:
            tableView.reloadData()
        }
        
        if let objects = controller.fetchedObjects {
            areas = objects as! [AreaMO]
        }
    }
    //當(dāng)控制器已經(jīng)處理完內(nèi)容變更時
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

七、真正的刪除

@修改之前tableView的刪除方法
            self.areas.remove(at: indexPath.row)
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context = appDelegate.persistentContainer.viewContext
            context.delete(self.fc.object(at: indexPath))
            appDelegate.saveContext()

//            此處需要注釋掉,因?yàn)槲覀円呀?jīng)控制了數(shù)據(jù)庫的刪除
//            tableView.deleteRows(at: [indexPath], with: .fade)
@然后更新對象
reviewVC.ratingCloser = { (value:String) -> Void in
            self.area.rating = value
            self.RatingBtn.setImage(UIImage(named: value), for: .normal)
                
        }
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.saveContext()
        
@重新讀取
if let rating = area.rating {
   self.RatingBtn.setImage(UIImage(named: rating), for: .normal)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,674評論 1 32
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,262評論 8 265
  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,211評論 3 119
  • 你是不是曾經(jīng)為了敬一個人的酒,而跑去敬一桌人的酒?然后,獨(dú)自傷感…… ...
    沫清風(fēng)閱讀 288評論 0 1
  • 看了一些文章,覺得寫寫文字還是比較好的,突發(fā)奇想:命運(yùn)是什么,是他想讓你去哪就去哪,讓你干什么就干什么的幕后導(dǎo)演,...
    美美的旭閱讀 217評論 0 0

友情鏈接更多精彩內(nèi)容