我在swift CoreData中有一个表,我保存了OrderTable类型的记录,并从该表中获取已保存的记录以重新加载表。在闭包的帮助下,我将该数组值分配给OrderTable类型的数组,该数组存储循环中的所有记录和打印值,但是当我从该数组重新加载单元格时,它在访问该对象的键时打印nil值。
请帮助我,我尝试了一切。这是我的代码并附上了问题的截图。
http://i.stack.imgur.com/sXbrZ.png
##OrderTable.swift database model file
## Save records in database
class OrderTable: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
class func createInManagedObjectContext(moc: NSManagedObjectContext, dict:[String:AnyObject]) -> OrderTable {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("OrderTable", inManagedObjectContext: moc) as? OrderTable
newItem?.closedDate = dict["closedDate"]as? String;
newItem?.modifiedDate = dict["modifiedDate"]as? String
newItem?.openedDate = dict["openedDate"]as? String
newItem!.items = dict["items"]as? NSData
newItem?.server = (dict["server"]as? String?)!
newItem?.orderNo = dict["orderNo"]as? String
newItem?.totalPrice = dict["totalPrice"]as? String
newItem?.tableName = dict["tableName"]as? String
moc.saveRecursively()
return newItem!
}
## Get records from database
class func getOrders(moc:NSManagedObjectContext,postCompleted : (succeeded: Bool, result:[OrderTable]?) -> ()){
// 9911882342 dilip
// var arrayRecords = [OrderTable]()
let fetchRequest = NSFetchRequest();
moc.performBlockAndWait({
let entityDescription = NSEntityDescription.entityForName("OrderTable",inManagedObjectContext: moc)
fetchRequest.entity = entityDescription
do {
let resultOrders = try moc.executeFetchRequest(fetchRequest)as? [OrderTable]
postCompleted(succeeded:true,result: resultOrders );
} catch {
let fetchError = error as NSError
debugPrint(fetchError)
postCompleted(succeeded: false, result: nil)
}
})
}
}
##Controller class to get and load table from database values
//
// OrderOpenAndCloseViewController.swift
// POSApp
//
import Foundation
import UIKit
import CoreData
class OrderOpenAndCloseViewController: UIViewController{
@IBOutlet weak var tableViewOrderListing: UITableView!
var arrayExistingOrders = [OrderTable]() // stores existing orders
let coreDataStack = CoreDataStack() // use for multithreaded coredata
let viewControllerUtils = ViewControllerUtils();// use for activity indicator
//MARK: view Life cycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated);
// call method to get records from database
getOpenExistingOrders();
}
//MARK: get all open existing orders from database
func getOpenExistingOrders(){
viewControllerUtils.showActivityIndicator(self.view)
if let newPrivateQueueContext =
self.coreDataStack.newPrivateQueueContext(){ // create new NSmanagedObject context
// call getOrder method of OrderTable to get orders from database with the help of closure and assign that to arrayExistingOrders of type OrderTable
OrderTable.getOrders(newPrivateQueueContext, postCompleted: { (succeeded, result) in
self.arrayExistingOrders = result!
let item = self.arrayExistingOrders.last // for value check get last object and print orderNo from that
print("order no =%@",item?.orderNo)// prints here value or in loop also 1000-001 etc
self.tableViewOrderListing.reloadData()
self.viewControllerUtils.hideActivityIndicator(self.view) // hide loader
})
}
}
}
//MARK: tableview datasource methods
extension OrderOpenAndCloseViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayExistingOrders.count // return number of orders
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("OrderOpenAndCloseCell", forIndexPath: indexPath)as? OrderOpenAndCloseCell
let item = arrayExistingOrders[indexPath.item]
print("orderNo =%@",item.orderNo) //here prints orderNo =%@ nil instead of value order no =%@ Optional("1000-001") etc
let orderNo = item.orderNo
var totalOrderCost:String?
if let totalcost = item.totalPrice{
totalOrderCost = totalcost
}else{
totalOrderCost = ""
}
let serverName = item.server
let openedDate = item.openedDate
cell?.labelOrderNo.text = orderNo;
cell?.labelServerName.text = serverName;
cell?.labelOpenedDate.text = openedDate
cell?.labelTotalPrice.text = totalOrderCost
return cell!;
}
}
答案 0 :(得分:1)
你的问题在这一行:
if let newPrivateQueueContext =
self.coreDataStack.newPrivateQueueContext
然后使用newPrivateQueueContext
执行提取。然后你让newPrivateContext
超出范围,这会导致它被解除分配。
当您获取托管对象时,该托管对象需要其托管对象上下文,但它不会对其进行强引用。如果取消分配托管对象上下文,则从中获取的任何托管对象现在都是无用的。您可以在上下文仍然存在的情况下打印结果 ,但只要您将其取消分配,就不能再使用结果了。
只要您需要使用fetch的结果,就需要对用于获取的上下文保持强引用。这可能意味着将它作为视图控制器的属性,但有很多方法可以做到这一点。