大寶劍之精挑細(xì)選——CoreData(四)

大寶劍的挑選是莊嚴(yán)而神圣的,必須一絲不茍的完成翘骂,防止出現(xiàn)自己約的炮含淚也得打完的慘劇壁熄。
(回到正題)當(dāng)我們讀取數(shù)據(jù)時,并不是每份數(shù)據(jù)都需要的碳竟,比如說有時候我們只想要女生的QQ~~~~~男生的QQ這時候給我我還得一個一個來挑選草丧,又偏了~~

  • 參考書籍:CORE DATA by Tutorials。
  • 默認(rèn)有swift基礎(chǔ)莹桅。
  • 默認(rèn)已閱讀上一篇內(nèi)容昌执。

這一篇的內(nèi)容:

  • 按條件查詢返回數(shù)量
  • 按條件查詢
  • 排序
  • 異步查詢
  • 批量同步

我們知道讀取數(shù)據(jù)之前我們必須創(chuàng)建一個讀取請求,這個讀取請求就是NSFetchRequest诈泼,這里有四種方法來創(chuàng)建一個NSFetchRequest
<pre><code>
//1
let fetchRequest1 = NSFetchRequest()
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext: managedObjectContext!) fetchRequest1.entity = entity!
//2
let fetchRequest2 = NSFetchRequest(entityName: "Person")
//3
let fetchRequest3 = managedObjectModel.fetchRequestTemplateForName("peopleFR")
//4
let fetchRequest4 = managedObjectModel.fetchRequestFromTemplateWithName("peopleFR",
substitutionVariables: ["NAME" : "Ray"])
</code></pre>

Have a look:

  • //1 //2這兩種就不多說了仙蚜,前面的篇章都遇到過,就是通過不同方法初始化厂汗,然后指定了Entity。
  • //3 這種方法用data model中的fetch request來初始化呜师,關(guān)于data model中的這個屬性娶桦,在后面會提到。
  • //4 這種方法同樣使用了data model中的fetch request汁汗,同時設(shè)定了一個斷言,來限定最后的輸出結(jié)果知牌。

一如既往的祈争,我們每一個篇章都會有一個Demo,今天的這個Demo較為復(fù)雜角寸,由書籍CORE DATA by Tutorials提供菩混,來看一下這個Demo:

在這個界面會顯示所有的奶茶店忿墅,點擊Filter按鈕以后會跳轉(zhuǎn)到刪選條件的界面。


2.png

在個界面會顯示刪選條件沮峡,刪選條件包括價格區(qū)間疚脐,$表示十美元以內(nèi),$$表示出售100美元的奶茶店邢疙,$$$表示出售1000美元奶茶的店棍弄。刪選條件還包括距離,是否有用戶評價疟游,還有根據(jù)字母排序........
來看一下文件結(jié)構(gòu):


3.png

其中Stats.seift呼畸、Venue.swift、Location.swift颁虐、PriceInfo.swift蛮原、Category.swift都是Entity生成的類,其他的文件都不是特別復(fù)雜聪廉,就不多說瞬痘。注意一下seed.json文件,這個文件提供了紐約地區(qū)真實的奶茶店情況~

開始完善我們的Demo板熊,我們首先要做的就是將所有的奶茶店顯示在TableView中框全,而所有的奶茶店則是存儲在Venue這個Entity中,所以我們要創(chuàng)建一個Fetch Request讀取Venue中的所有數(shù)據(jù)干签,至于這些數(shù)據(jù)什么時候存進去的津辩?打開我們的AppDelegate.swift,我們在進入程序的最開始已經(jīng)將seed.json中的所有數(shù)據(jù)都存起來了容劳,至于怎么存的喘沿,這不在今天的考慮當(dāng)中。
打開Model.xcdatamodeld竭贩,長按Add Entity蚜印,不要放開鼠標(biāo),選擇Add Fetch Request留量,這樣我們在data model中添加了一個Fetch Request窄赋,

4.png

選擇我們新建的Fetch Request,將Fetch All選擇為Venue楼熄,這一步講Fetch Request與Entity聯(lián)系起來:
與Entity聯(lián)系起來

打開ViewConreoller.swift忆绰,先是添加頭文件

      import CoreData

添加存放讀取數(shù)據(jù)的數(shù)組,和讀取數(shù)據(jù)的請求:

  var fetchRequest: NSFetchRequest!
  var venues: [Venue]!

在viewDidLoad方法中添加一下代碼:
<pre><code>
//1
fetchRequest = coreDataStack.model.fetchRequestTemplateForName("FetchRequest")
//2
fetchAndReload()

</code></pre>

  • //1 這個就是我們前面提到的第三種創(chuàng)建Fetch Request的方法可岂,這種方法從data model中創(chuàng)建的Fetch Request來進行初始化错敢,而在模板中我們已經(jīng)吧這個Fetch Request與Entity聯(lián)系起來了。
  • //2 這個方法我們在TableView中顯示數(shù)據(jù)缕粹,當(dāng)然我們還沒有添加這個方法稚茅,接下來就是添加這個方法:

<pre><code>
func fetchAndReload(){
var error: NSError?
let results = coreDataStack.context.executeFetchRequest(fetchRequest,error: &error) as! [Venue]?
if let fetchedResults = results { venues = fetchedResults
} else {
println("Could not fetch (error), (error!.userInfo)")
}
tableView.reloadData()
}
</pre></code>

這個方法就不進行解釋了纸淮,前面的篇章中已經(jīng)反復(fù)寫過很多次了。
我們已經(jīng)把所有的奶茶店的數(shù)據(jù)都讀取到[Venue]數(shù)組中了峰锁,接下來就是在TableView中顯示這些數(shù)據(jù)萎馅,以下代碼:

<pre><code>
func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
return venues.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath
indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("VenueCell") as! UITableViewCell
let venue = venues[indexPath.row]
cell.textLabel!.text = venue.name
cell.detailTextLabel!.text = venue.priceInfo.priceCategory
return cell
}
</code></pre>

代碼簡單就不進行解釋了,有問題的同學(xué)虹蒋,可以留言提問糜芳,好的,來讓我們運行下程序吧魄衅。


大功告成峭竣,成功將所有的奶茶店顯示在了界面上

NSFetchReuqest是多功能的,他的返回值不僅僅可以是對象晃虫,他同樣可以查詢數(shù)據(jù)的數(shù)量皆撩,平均值、最大值哲银、最小值······他有一個屬性叫做resultType通過設(shè)定這個屬性扛吞,你可以通過查詢返回不同的結(jié)果,這是所有的返回類型:

  • NSManagedObjectResultType:這是默認(rèn)的選項荆责,返回了所有的對象滥比。
  • NSCountResultType:返回所有對象的數(shù)量。
  • NSDictionaryResultType:對查詢結(jié)果進行統(tǒng)計做院,包括求和盲泛,最大值,最小值等等等键耕。好多好多寺滚,要不要列出來?算來還不列了屈雄,點進xcode的解釋里頭村视,全列出來了。
  • NSManagedObjectIDResultType: 返回所有對象的ID酒奶,這個方法現(xiàn)在已經(jīng)被淘汰了蚁孔,淘汰了就不多說了。

返回數(shù)量

來到我們的刪選界面讥蟆,在這個界面的最上節(jié),我們將返回不同價格的奶茶店的數(shù)量纺阔。
打開FilterViewController.swift瘸彤,添加以下代碼:

   import CoreData
   var coreDataStack:CoreDataStack!

返回ViewController.swift,在prepareForSegue函數(shù)中添加以下代碼:

  filterVC.coreDataStack = coreDataStack

將暫存器傳過去~~而不用重新新建一個笛钝。

再回到FilterViewController.swift质况,我們首先創(chuàng)建一個懶惰屬性:
<pre><code>
lazy var cheapVenuePredicate: NSPredicate = {
var predicate = NSPredicate(format: "priceInfo.priceCategory == %@", "$")
return predicate
}()

</code></pre>

懶惰屬性的意思就是在使用到這個屬性的時候才會去創(chuàng)建這個變量愕宋,而不是在最開始創(chuàng)建。那么這個懶惰屬性的作用是什么呢结榄,這個懶惰屬性可以限定我們的查詢結(jié)果中贝,在這個懶惰屬性中,就是限定priceInfo.priceCategory是“$”臼朗,繼續(xù)在這個頁面中添加以下代碼:
<pre><code>
func populateCheapVenueCountLabel() {
// $ fetch request
//1
let fetchRequest = NSFetchRequest(entityName: "Venue")
//2
fetchRequest.resultType = NSFetchRequestResultType.CountResultType
fetchRequest.predicate = cheapVenuePredicate
//3
var error: NSError?
let result = coreDataStack.context.executeFetchRequest(fetchRequest,error: &error) as! [NSNumber]?
if let countArray = result {
let count = countArray[0].integerValue
firstPriceCategoryLabel.text = "(count) bubble tea places"
} else {
println("Could not fetch (error), (error!.userInfo)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
populateCheapVenueCountLabel()
}
</code></pre>

  • //1 新建了一個** NSFetchRequest**
  • //2 指定了resultType為NSFetchRequestResultType.CountResultType邻寿,當(dāng)這么指定以后,讀取的返回結(jié)果就是對象的數(shù)量视哑。
    指定了刪選條件绣否,就是我們之前設(shè)定的斷言。
  • //3 讀取結(jié)果挡毅,結(jié)果返回一個NSNumber的數(shù)組蒜撮,這個數(shù)組只有一個值,所以我們獲取個數(shù)保存在result[0]中跪呈。
    將讀取到的結(jié)果顯示在界面上段磨。

同樣的道理,我們用同樣的方法獲取了價格為“$$”的個數(shù)耗绿。代碼如下:
<pre><code>
lazy var moderateVenuePredicate: NSPredicate = {
var predicate = NSPredicate(format: "priceInfo.priceCategory == %@", "$$")
return predicate
}()
func populateModerateVenueCountLabel() {
// $$ fetch request
let fetchRequest = NSFetchRequest(entityName: "Venue")
fetchRequest.resultType = .CountResultType
fetchRequest.predicate = moderateVenuePredicate
var error: NSError?
let result = coreDataStack.context.executeFetchRequest(fetchRequest,error: &error) as! [NSNumber]?
if let countArray = result {
let count = countArray[0].integerValue
secondPriceCategoryLabel.text = "(count) bubble tea places"
} else {
println("Could not fetch (error), (error!.userInfo)")
}
}
</code></pre>

我們現(xiàn)在來運行一下程序來看一下結(jié)果苹支,如下圖所示:


1.png

我們已經(jīng)計算出了“$”和"$$"的價格的奶茶店的個數(shù),事實上我們有一種更好的方式來計算對象的個數(shù)缭乘,如以下代碼所示:
<pre><code>
lazy var expensiveVenuePredicate: NSPredicate = {
var predicate = NSPredicate(format: "priceInfo.priceCategory == %@", "$$$")
return predicate
}()
func populateExpensiveVenueCountLabel() {
// $$$ fetch request
let fetchRequest = NSFetchRequest(entityName: "Venue")
fetchRequest.predicate = expensiveVenuePredicate
var error: NSError?
let count = coreDataStack.context.countForFetchRequest(fetchRequest,error: &error)
if count == NSNotFound {
println("Could not fetch (error), (error!.userInfo)")
}
thirdPriceCategoryLabel.text = "(count) bubble tea places"
}

</code></pre>

同樣我們設(shè)定了一個斷言沐序,來限制了查詢結(jié)果,但是在這里我們沒有設(shè)定他的返回就結(jié)果堕绩,而是用到了這樣一個方法

 func countForFetchRequest(request: NSFetchRequest, error: NSErrorPointer) -> Int

這個方法同樣會返回查詢結(jié)果對象的數(shù)量策幼。來看一下最終的運行結(jié)果吧:

1.png

wonderful!奴紧!~~~特姐,一共27家“$”級別奶茶店,兩家"$$"級別奶茶店黍氮,一家"$$$"級別奶茶店唐含。

呼呼~~~休息休息,我去喝杯奶茶再回來~


X只能喝一杯十元的奶茶了沫浆,很想知道那千元奶茶店捷枯,賣的是啥~~~

好的我們來完成第二個模塊。
對各種服務(wù)進行統(tǒng)計专执,就是我們前面提到的第三種返回類型淮捆,真的是很黃很暴力哈。添加以下代碼:
<pre><code>
func populateDealsCountLabel() {
//1
let fetchRequest = NSFetchRequest(entityName: "Venue")
fetchRequest.resultType = .DictionaryResultType
//2
let sumExpressionDesc = NSExpressionDescription()
sumExpressionDesc.name = "sumDeals"
//3
sumExpressionDesc.expression = NSExpression(forFunction: "sum:",arguments:[NSExpression(forKeyPath: "specialCount")])
sumExpressionDesc.expressionResultType = NSAttributeType.Integer32AttributeType
//4
fetchRequest.propertiesToFetch = [sumExpressionDesc]
//5
var error: NSError?
let result = coreDataStack.context.executeFetchRequest(fetchRequest,error: &error) as! [NSDictionary]?
if let resultArray = result {
let resultDict = resultArray[0]
let numDeals: AnyObject? = resultDict["sumDeals"]
numDealsLabel.text = "(numDeals!) total deals"
} else {
println("Could not fetch (error), (error!.userInfo)")
}
}
</code></pre>

  • //1 新建一個NSFetchRequest,將返回類型設(shè)定為 . DictionaryResultType攀痊。
  • 因為返回類型是一個字典形桐腌,所以在這里要設(shè)置key為sumDeals,也就是這里的name苟径。
  • 這里統(tǒng)計的是specialCount的和案站,** forFunction**填的是“sum:”其實這里有好多可以填的,點進這個方法棘街,你可以看到好多~好多~好多~~其實這里就是給設(shè)定一個統(tǒng)計的方式蟆盐。
  • 設(shè)定** .propertiesToFetch**屬性。
  • 發(fā)出請求蹬碧,返回一個字典型舱禽。key就是我們前面設(shè)定的sumDeals。

運行一下APP:

一共12次交易記錄

接下來的功能是這樣的:在Fiters界面選擇刪選條件以后恩沽,點擊右上方的Search按鈕誊稚,返回上一屆面,按條件顯示對象,那我們第一步要做的就是將選擇的條件返回上一界面,再上一界面的TableView中顯示符合條件的對象繁涂,我們用協(xié)議來傳遞參數(shù)揪利,添加協(xié)議:
<pre><code>
protocol FilterViewControllerDelegate: class {
func filterViewController(filter: FilterViewController,didSelectPredicate predicate:NSPredicate?,sortDescriptor:NSSortDescriptor?)
}
</code></pre>

在Search方法中添加以下代碼
<pre><code>
@IBAction func saveButtonTapped(sender: UIBarButtonItem) {
delegate!.filterViewController(self, didSelectPredicate: selectedPredicate, sortDescriptor: selectedSortDescriptor)
dismissViewControllerAnimated(true, completion:nil)
}
</code></pre>

這段代碼很明顯就是在點擊Search按鈕,返回界面以前執(zhí)行在viewConreoller中的方法** filterViewController**,并將參數(shù)傳過去。
添加刪選條件參數(shù)變量,前面提到了兩種刪選條件變量類型狼电,NSSortDescriptor和NSPredicate:
<pre><code>
weak var delegate: FilterViewControllerDelegate?
var selectedSortDescriptor: NSSortDescriptor?
var selectedPredicate: NSPredicate?
</code></pre>

前面我們已經(jīng)刪選過"$","$$","$$$"三個價位的奶茶店的數(shù)量,現(xiàn)在我們來顯示符合條件的奶茶店弦蹂,和之前的區(qū)別在哪里肩碟,區(qū)別就是前面我們的查詢返回結(jié)果是NSFetchRequestResultType.CountResultType,而現(xiàn)在則是默認(rèn)的凸椿,返回對象即可削祈,而我們之前寫的刪選條件則是一樣的,在

   func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 

中添加選擇結(jié)果:
<pre><code>
//1
let cell = tableView.cellForRowAtIndexPath(indexPath)!
switch cell {
// Price section
case cheapVenueCell:
selectedPredicate = cheapVenuePredicate
case moderateVenueCell:
selectedPredicate = moderateVenuePredicate
case expensiveVenueCell:
selectedPredicate = expensiveVenuePredicate
default:
println("default case"
}
//2
cell.accessoryType = .Checkmark
</code></pre>

  • //1 根據(jù)選擇結(jié)果脑漫,確定判斷條件髓抑,這三個斷言在之前已經(jīng)寫過了。
  • //2 這個只是給選擇的項目打個勾优幸,而已~~~~

好的我們來到viewController.swift來實現(xiàn)一下代理方法吨拍,并添加代理:
添加代理:

 class ViewController: UIViewController,FilterViewControllerDelegate{

prepareForSegue方法中添加(關(guān)于協(xié)議,就不解釋了~~不懂的可以留言~):

 filterVC.delegate = self

好的网杆,實現(xiàn)方法:
<pre><code>
func filterViewController(filter: FilterViewController, didSelectPredicate predicate:NSPredicate?, sortDescriptor:NSSortDescriptor?) {
//1
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = nil
//2
if let fetchPredicate = predicate {
fetchRequest.predicate = fetchPredicate
}
if let sr = sortDescriptor {
fetchRequest.sortDescriptors = [sr]
}
//3
fetchAndReload()
}
</code></pre>

  • //1 先將兩個參數(shù)初始化為nil羹饰,因為我們傳過來的判斷條件參數(shù)只有一個是有值握爷。
  • //2 用if let來判斷到底哪個參數(shù)是有值的。
  • //3 最后一步更新一下界面严里。

來讓我們運行一下app,選擇“$”級別奶茶店追城,再點擊Search按鈕刹碾,不出意外,果然崩潰了座柱,為什么呢迷帜,因為我們的fetchrequest是從data model獲取的,而從data model獲取的fetchrequest是不可更改的色洞,而我們給他添加了一個判斷條件戏锹,所以崩潰了,解決方法很簡單火诸,換一個fetchRequest不就好了锦针,如以下操作:

<pre><code>
override func viewDidLoad() {
super.viewDidLoad()
// fetchRequest = coreDataStack.model.fetchRequestTemplateForName("FetchRequest")
fetchRequest = NSFetchRequest(entityName: "Venue")
fetchAndReload()
}
</code></pre>

我們再來運行下app,選擇“$$”置蜀,再點擊“Search”按鈕奈搜,結(jié)果如果所示:

果然就兩家啊

其他的判斷條件也是只差刪選的斷言就可以進行一樣的刪選功能了:

500米以內(nèi),判斷條件如下:

<pre><code>
lazy var walkingDistancePredicate: NSPredicate = {
var pr = NSPredicate(format: "location.distance < 500")
return pr
}()
</code></pre>

有用戶評價盯荤,判斷條件如下:

<pre><code>
lazy var hasUserTipsPredicate: NSPredicate = {
var pr = NSPredicate(format: "stats.tipCount > 0")
return pr
}()
</code></pre>
按名字升序排序:
<pre><code>
lazy var nameSortDescriptor: NSSortDescriptor = {
var sd = NSSortDescriptor(key: "name",ascending: true,selector: "localizedStandardCompare:")
return sd
}()
</pre></code>
按距離升序排序:
<pre><code>
lazy var distanceSortDescriptor: NSSortDescriptor = {
var sd = NSSortDescriptor(key: "location.distance",ascending: true)
return sd
}()
</pre></code>

按照價格升序:

<pre><code>
lazy var priceSortDescriptor: NSSortDescriptor = {
var sd = NSSortDescriptor(key: "priceInfo.priceCategory", ascending: true)
return sd
}()
</pre></code>

最后一步就是在TableView選擇方法中初始化刪選條件馋吗,像這樣:
<pre><code>
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!

    switch cell {
        // Price section
    case cheapVenueCell:
            selectedPredicate = cheapVenuePredicate
    case moderateVenueCell:
            selectedPredicate = moderateVenuePredicate
    case expensiveVenueCell:
            selectedPredicate = expensiveVenuePredicate
    case offeringDealCell:
            selectedPredicate = offeringDealPredicate
    case walkingDistanceCell:
            selectedPredicate = walkingDistancePredicate
    case userTipsCell:
            selectedPredicate = hasUserTipsPredicate
    case nameAZSortCell:
            selectedSortDescriptor = nameSortDescriptor
    case nameZASortCell:
            selectedSortDescriptor = nameSortDescriptor.reversedSortDescriptor as? NSSortDescriptor
    case distanceSortCell:
            selectedSortDescriptor = distanceSortDescriptor
    case priceSortCell:
            selectedSortDescriptor = priceSortDescriptor
        
    default:
                println("default case")
    }
        
    cell.accessoryType = .Checkmark
}

</code></pre>

很靈哈~~

異步獲取,在獲取大量數(shù)據(jù)的時候秋秤,可能會使程序無法響應(yīng)宏粤,用戶的操作,這個就很糟糕灼卢,如果可以異步獲取的話绍哎,那么再獲取數(shù)據(jù)的同時,用戶還可以進行操作芥玉,這就顯的十分友好蛇摸。
返回 viewcontroller.swift,在viewDidLoad()中添加以下代碼:

<pre><code>
//2
asyncFetchRequest = NSAsynchronousFetchRequest(fetchRequest: fetchRequest){
[unowned self] (result: NSAsynchronousFetchResult! ) -> Void in
self.venues = result.finalResult as! [Venue]
self.tableView.reloadData() }
//3
var error: NSError?
let results = coreDataStack.context.executeRequest(asyncFetchRequest,error: &error)
if let persistentStoreResults = results {
//Returns immediately, cancel here if you want
} else {
println("Could not fetch (error), (error!.userInfo)")
}
</code></pre>

  • //3 這個指的是在完成查詢以后進行的操作灿巧,完成數(shù)據(jù)讀取以后當(dāng)然是更新tableview赶袄。

因為我們進行的是異步讀取,所以剛進入程序時[Venue]為空抠藕,這樣初始化TableView的話饿肺,會使程序崩潰,最簡單的解決方法就是這樣:

   [Venue] = []

要進行異步讀取還有最后一步要做盾似,打開我們的CoreDataStack.swift文件將
context = NSManagedObjectContext()更改為

  context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)

好的敬辣,我們再把程序運行一下雪标,你會發(fā)現(xiàn)運行結(jié)果與之前一模一樣,這是因為數(shù)據(jù)數(shù)量較少的緣故溉跃,當(dāng)數(shù)據(jù)規(guī)模增大的時候則會顯現(xiàn)出很大的區(qū)別村刨。


批量更新,更新的時候我們不能說全部都重新存一遍哈撰茎,數(shù)量少的時候還好說嵌牺,數(shù)量多的時候這樣做就太糟糕了。
<pre><code>
//1
let batchUpdate = NSBatchUpdateRequest(entityName: "Venue")
//2
batchUpdate.propertiesToUpdate = ["favorite" : NSNumber(bool: true)]
//3
batchUpdate.affectedStores = coreDataStack.psc.persistentStores
//4
batchUpdate.resultType = .UpdatedObjectsCountResultType
//5
var batchError: NSError?
let batchResult = coreDataStack.context.executeRequest(batchUpdate,error: &batchError) as! NSBatchUpdateResult?
if let result = batchResult {
println("Records updated (result.result)")
} else {
println("Could not update (batchError), (batchError!.userInfo)")
}
</code></pre>

  • //1 批量更新其實很簡單哈龄糊,先是創(chuàng)建一個NSBatchUpdateRequest和Entity聯(lián)系起來逆粹。
  • //2 通過batchUpdate.propertiesToUpdate屬性來確定要更新的內(nèi)容。
  • //3 確定更新的對象炫惩,時候影響到數(shù)據(jù)庫僻弹。
  • //4 確定返回內(nèi)容,我們這里返回更新的個數(shù)
一共更新了30條

這一篇的內(nèi)容大概就是這樣了他嚷,總結(jié)一下蹋绽,其實就是通過設(shè)定返回類型,和刪選條件來讀取不同的數(shù)據(jù),然后還有異步獲取筋蓖,最后講了批量更新蟋字。

喝杯奶茶緩緩~~~~~

初始模板以上傳github:https://github.com/superxlx/BubbleTea
源代碼已上傳github:https://github.com/superxlx/CoreDataTest4

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扭勉,隨后出現(xiàn)的幾起案子鹊奖,更是在濱河造成了極大的恐慌,老刑警劉巖涂炎,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忠聚,死亡現(xiàn)場離奇詭異,居然都是意外死亡唱捣,警方通過查閱死者的電腦和手機两蟀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來震缭,“玉大人赂毯,你說我怎么就攤上這事〖鹪祝” “怎么了党涕?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巡社。 經(jīng)常有香客問我膛堤,道長,這世上最難降的妖魔是什么晌该? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任肥荔,我火速辦了婚禮绿渣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘燕耿。我一直安慰自己中符,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布誉帅。 她就那樣靜靜地躺著舟茶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堵第。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天隧出,我揣著相機與錄音踏志,去河邊找鬼。 笑死胀瞪,一個胖子當(dāng)著我的面吹牛针余,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凄诞,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼圆雁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帆谍?” 一聲冷哼從身側(cè)響起伪朽,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汛蝙,沒想到半個月后烈涮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡窖剑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年坚洽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片西土。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡讶舰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出需了,到底是詐尸還是另有隱情跳昼,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布肋乍,位于F島的核電站庐舟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏住拭。R本人自食惡果不足惜挪略,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一历帚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杠娱,春花似錦挽牢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至室叉,卻和暖如春睹栖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茧痕。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工野来, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人踪旷。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓曼氛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親令野。 傳聞我的和親對象是個殘疾皇子舀患,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)气破,斷路器聊浅,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件现使、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評論 4 62
  • 歷史上她是一個傾國傾城的不可多得的美人狗超。 嫁給過李隆基的兒子壽王,后來又轉(zhuǎn)嫁給了一代帝王李隆基朴下。后來成了一個禍國殃...
    高冷范的逗比閱讀 532評論 0 1
  • 爆裂鼓手 是一部讓你無法停下來去干其他事情的電影努咐, 因為每一幕都太牽動人心了。 緊湊的剪輯殴胧,優(yōu)質(zhì)的表演渗稍,戲劇的沖突...
    第8日影院閱讀 400評論 0 0
  • 觀影,已然成為我生活中必不可少的一件樂事团滥。很多時候竿屹,我都覺得,一個人在觀影的同時灸姊,也同樣能看見一部分失靈的...
    失靈者閱讀 1,434評論 0 4