Coredata managedObject问题swift

时间:2016-07-16 06:40:17

标签: ios swift uitableview core-data

我在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!;
        }
      }

1 个答案:

答案 0 :(得分:1)

你的问题在这一行:

if let newPrivateQueueContext =
    self.coreDataStack.newPrivateQueueContext

然后使用newPrivateQueueContext执行提取。然后你让newPrivateContext超出范围,这会导致它被解除分配。

当您获取托管对象时,该托管对象需要其托管对象上下文,但它不会对其进行强引用。如果取消分配托管对象上下文,则从中获取的任何托管对象现在都是无用的。您可以在上下文仍然存在的情况下打印结果 ,但只要您将其取消分配,就不能再使用结果了。

只要您需要使用fetch的结果,就需要对用于获取的上下文保持强引用。这可能意味着将它作为视图控制器的属性,但有很多方法可以做到这一点。