使用 Coredata 学习 Swift:为啥我没有得到任何 UITableViewCells?

Posted

技术标签:

【中文标题】使用 Coredata 学习 Swift:为啥我没有得到任何 UITableViewCells?【英文标题】:Learning Swift with Coredata: why don't I get any UITableViewCells?使用 Coredata 学习 Swift:为什么我没有得到任何 UITableViewCells? 【发布时间】:2015-02-25 07:44:07 【问题描述】:

我将我最近的 Swift 自学项目从使用 NSMutableArray 转换为使用 CoreData。

我希望我的程序执行的是:

连接到受登录名/密码保护的页面并下载最近 100 张图片及其时间戳的列表 对于此列表中的每张图片,创建一个 NSManagedObject (PicInfo)(如果不存在包含相同图片 url 的现有对象 - 尚未实现,我猜它与 NSPredicate 有关)。 在 UITableView 中按时间戳降序显示这些对象中的每一个

虽然我曾经有一个带有初始非 CoreData 的 little issues(我不得不触摸 UITableView 让它显示任何内容并且刷新挂起应用程序,但 CoreData 变得更糟:UITableView 仍然是空的,尽管我知道我在存储对象:

Got data!
Refresh will start
MVC::insertNewObject beginning
PicInfo init: found 0: [viewz/CAM_HALL_1_20150225074135_4324.jpg] taken at 2015/02/25 07:41:35
MVC::insertNewObject about to insert Object 0 - http://my.webcam.site.perso/CAM_HALL_1_20150225074135_4324.jpg
2015-02-25 07:41:55.497 spEye[21867:2544527] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1377
2015-02-25 07:41:55.498 spEye[21867:2544527] CoreData: error: Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update with userInfo (null)
MVC::insertNewObject successfully inserted Object 0 - http://my.webcam.site.perso/CAM_HALL_1_20150225074135_4324.jpg
MVC::insertNewObject beginning
PicInfo init: found 1: [viewz/CAM_HALL_1_20150225074129_4323.jpg] taken at 2015/02/25 07:41:30
MVC::insertNewObject about to insert Object 1 - http://my.webcam.site.perso/CAM_HALL_1_20150225074129_4323.jpg
MVC::insertNewObject successfully inserted Object 1 - http://my.webcam.site.perso/CAM_HALL_1_20150225074129_4323.jpg
MVC::insertNewObject beginning
PicInfo init: found 2: [viewz/CAM_HALL_1_20150225074124_4322.jpg] taken at 2015/02/25 07:41:24
MVC::insertNewObject about to insert Object 2 - http://my.webcam.site.perso/CAM_HALL_1_20150225074124_4322.jpg
MVC::insertNewObject successfully inserted Object 2 - http://my.webcam.site.perso/CAM_HALL_1_20150225074124_4322.jpg
...
Refresh completed

所以我真的被困住了,害怕失去耐心并回到 Objective-C。有人会好心看看我的代码并告诉我我做错了什么吗?

代码如下:

MasterViewController

import UIKit
import CoreData

let baseUrlString = "http://my.webcam.site.perso"
let username = "mylogin"
let password = "v3rys3cr3tp4s$"

class MasterViewController: UITableViewController,NSFetchedResultsControllerDelegate,NSURLConnectionDataDelegate 

    var detailViewController: DetailViewController? = nil
    var managedObjectContext: NSManagedObjectContext? = nil
    var loading: Bool = false;


    override func awakeFromNib() 
        super.awakeFromNib()
        if UIDevice.currentDevice().userInterfaceIdiom == .Pad 
            self.clearsSelectionOnViewWillAppear = false
            self.preferredContentSize = CGSize(width: 320.0, height: 600.0)
        
    

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        if let split = self.splitViewController 
            let controllers = split.viewControllers
            self.detailViewController = controllers[controllers.count-1].topViewController as? DetailViewController
        
        self.refreshControl?.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
        self.refresh(self)
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func insertNewObject(sender: AnyObject, details: NSString) 
        println("MVC::insertNewObject beginning")
        let context = self.fetchedResultsController.managedObjectContext
        let entity = self.fetchedResultsController.fetchRequest.entity!
        var picInfo=PicInfo(data: details)
        println("MVC::insertNewObject about to insert Object \(picInfo.index) - \(picInfo.url)")

        let newManagedObject = picInfo.managedObject(entity, context:context)

        // Save the context.
        var error: NSError? = nil
        if !context.save(&error) 
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            //println("Unresolved error \(error), \(error.userInfo)")
            println("MVC::insertNewObject *could not* insert Object \(picInfo.index) - \(picInfo.url)")
            abort()
        
        println("MVC::insertNewObject successfully inserted Object \(picInfo.index) - \(picInfo.url)")
    

    // MARK: - Segues

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        if segue.identifier == "showDetail" 
            if let indexPath = self.tableView.indexPathForSelectedRow() 
            let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
                let controller = (segue.destinationViewController as UINavigationController).topViewController as DetailViewController
                controller.detailItem = object
                controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
                controller.navigationItem.leftItemsSupplementBackButton = true
            
        
    

    // MARK: - Table View

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return (self.fetchedResultsController.sections?[section] as? NSFetchedResultsSectionInfo)?.numberOfObjects ?? 0
    


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        self.configureCell(cell, atIndexPath: indexPath)
        return cell
    

    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
        // Return false if you do not want the specified item to be editable.
        return false
    

    func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) 
       if let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as? PicInfo 
            println("configureCell: \(object.index)")
            var todo=""
            if (object.downloading || !object.downloaded) 
                todo="(*)"
            
            cell.textLabel!.text = "\(object.index): \(object.desc)\(todo)"
            cell.detailTextLabel?.text = object.stamp
            if (!object.downloaded) 
                object.loadImage()
            
            if var img = object.image
                cell.imageView?.image = img
            
         else 
            println("configureCell: object#\(indexPath.row) not found !?")
        
    

    // MARK: - Fetched results controller

    var fetchedResultsController: NSFetchedResultsController 
        if _fetchedResultsController != nil 
            return _fetchedResultsController!
        

        let fetchRequest = NSFetchRequest()
        // Edit the entity name as appropriate.
        let entity = NSEntityDescription.entityForName("PicInfo", inManagedObjectContext: self.managedObjectContext!)
        fetchRequest.entity = entity

        // Set the batch size to a suitable number.
        fetchRequest.fetchBatchSize = 100

        // Edit the sort key as appropriate.
        let sortDescriptor = NSSortDescriptor(key: "stamp", ascending: false)
        let sortDescriptors = [sortDescriptor]

        fetchRequest.sortDescriptors = [sortDescriptor]

        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
        aFetchedResultsController.delegate = self
        _fetchedResultsController = aFetchedResultsController

        var error: NSError? = nil
        if !_fetchedResultsController!.performFetch(&error) 
             // Replace this implementation with code to handle the error appropriately.
             // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
             println("Unresolved error \(error), \(error?.description)")
             abort()
        

        return _fetchedResultsController!
        
    var _fetchedResultsController: NSFetchedResultsController? = nil

    func controllerWillChangeContent(controller: NSFetchedResultsController) 
        self.tableView.beginUpdates()
    

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) 
        switch type 
            case .Insert:
                tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
            case .Delete:
                tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
            case .Update:
                if let thecell=tableView.cellForRowAtIndexPath(indexPath!) 
                    println("MVC::didChangeObject: cell exists at \(indexPath?.row)")
                    self.configureCell(thecell, atIndexPath: indexPath!)
                 else 
                    println("MVC::didChangeObject: nil cell at \(indexPath?.row)\n\(tableView.description)")
            
            case .Move:
                tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
                tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
            default:
                return
        
    

    func controllerDidChangeContent(controller: NSFetchedResultsController) 
        self.tableView.endUpdates()
    

    /*
     // Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed.

     func controllerDidChangeContent(controller: NSFetchedResultsController) 
         // In the simplest, most efficient, case, reload the table view.
         self.tableView.reloadData()
     
     */

    // MARK: - Refresh
    func refresh(sender:AnyObject)
    
        self.tableView.beginUpdates()
        self.loadPictureList()
        self.tableView.endUpdates()
    

    // MARK: Internet stuff

    func loadPictureList () 
        // set up the base64-encoded credentials
        if (self.loading) 
            return
        
        self.loading = true
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        let loginString = NSString(format: "%@:%@", username, password)
        let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
        let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
        let authString = "Basic \(base64LoginString)"
        config.HTTPAdditionalHeaders = ["Authorization" : authString]
        let session = NSURLSession(configuration: config)

        // create the request
        let url = NSURL(string: baseUrlString + "/latest.php")
        let request = NSMutableURLRequest(URL: url!)

        // fire off the request
        var task = session.dataTaskWithURL(url!)
            (data, response, error) -> Void in
            if error != nil 
                self.handlePictureList("", encounteredProblem:"\(error.localizedDescription)\nurl:\(url)")
             else 
                var result = NSString(data: data, encoding: NSASCIIStringEncoding)!
                self.handlePictureList(result, encounteredProblem:"")
            
        
        task.resume()

    

    func handlePictureList (data: NSString, encounteredProblem error: NSString) 
        if (error.length>0) 
            println ("Had error: [\(error)]")
         else 
            println ("Got data!")
            println("Refresh will start")
            var pixArr = data.componentsSeparatedByString("\n")
            for unparsedPicInfo in pixArr 
                if (unparsedPicInfo.hasPrefix("<tr>")) 
                    var picInfo=unparsedPicInfo.stringByReplacingOccurrencesOfString("<tr><td>", withString: "")
                    picInfo=picInfo.stringByReplacingOccurrencesOfString("</td></tr>", withString: "")
                    picInfo=picInfo.stringByReplacingOccurrencesOfString("</td><td>", withString: "\t")
                    self.insertNewObject(self, details:picInfo)
                
            
            self.loading = false
            println("Refresh is over")

        
        return
    


图片信息

import Foundation
import UIKit
import CoreData

class PicInfo 
    var index: Int = 0
    var desc: String = ""
    var stamp: String = ""
    var url: String = ""
    var image: UIImage!
    var downloaded: Bool = false;
    var downloading: Bool = false;

    init(data: String) 
        var picInfos=data.componentsSeparatedByString("\t")
        println("PicInfo init: found \(picInfos[0]): [\(picInfos[2])] taken at \(picInfos[1])")
        self.index = picInfos[0].toInt()!
        self.url = baseUrlString + "/" + picInfos[2]
        self.stamp = picInfos[1]
        desc = ""
        if (picInfos[2].rangeOfString("CAM_HALL") != nil) 
            desc="Hall"
         else if (picInfos[2].rangeOfString("CAM_STAIRS") != nil) 
            desc="Stairs"
         else 
            desc="Cats"
        
        self.image = UIImage(named: "nothingtosee")
        self.loadImage()
    

    func URL() -> NSURL 
        var URL=NSURL(string: self.url)
        return URL!
    

    func managedObject(entity: NSEntityDescription, context: NSManagedObjectContext) -> NSManagedObject 
        let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) as NSManagedObject
        newManagedObject.setValue(index, forKey: "index")
        newManagedObject.setValue(desc, forKey: "desc")
        newManagedObject.setValue(stamp, forKey: "stamp")
        newManagedObject.setValue(url, forKey: "url")
        newManagedObject.setValue(UIImageJPEGRepresentation(image,80), forKey: "image")
        newManagedObject.setValue(downloaded, forKey: "downloaded")
        newManagedObject.setValue(downloading, forKey: "downloading")

        return newManagedObject;
    

    func loadImage() 
        if (self.downloading) 
            return
        
        let url = self.URL()
        let request = NSMutableURLRequest(URL: url)
        let loginString = NSString(format: "%@:%@", username, password)
        let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
        let base64LoginString = loginData.base64EncodedStringWithOptions(nil)

        // create the request
        request.HTTPMethod = "POST"
        request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
        self.downloading = true
        NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: (response: NSURLResponse!,data: NSData!,error: NSError!) -> Void in
            if error == nil 
                if let blob = data 
                    self.image = UIImage(data: blob)
                    self.downloaded = true
                
            
            else 
                println("Error: \(error.localizedDescription)")
            
            self.downloading = false
        )
    

编辑 1 添加 numberOfRowsInSection 方法。

现在 UITableView 显示记录(默认值),但在我可以交互之前崩溃(并清空 TableView)。

日志给出:

Got data!
Refresh will start
MVC::insertNewObject beginning
PicInfo init: found 0: [viewz/00D6FB01ABB1()_1_20150225175206_7382.jpg] taken at 2015/02/25 17:52:05
MVC::insertNewObject about to insert Object 0 - http://my.site.perso/00D6FB01ABB1()_1_20150225175206_7382.jpg
configureCell: object#0 not found !?
MVC::insertNewObject successfully inserted Object 0 - http://my.site.perso/00D6FB01ABB1()_1_20150225175206_7382.jpg
MVC::insertNewObject beginning
PicInfo init: found 1: [viewz/00D6FB01ABB1()_1_20150225175200_7381.jpg] taken at 2015/02/25 17:52:00
MVC::insertNewObject about to insert Object 1 - http://my.site.perso/00D6FB01ABB1()_1_20150225175200_7381.jpg
configureCell: object#1 not found !?
MVC::insertNewObject successfully inserted Object 1 - http://my.site.perso/00D6FB01ABB1()_1_20150225175200_7381.jpg
MVC::insertNewObject beginning
PicInfo init: found 2: [viewz/00D6FB01ABB1()_1_20150225175155_7380.jpg] taken at 2015/02/25 17:51:55

....snip....

MVC::insertNewObject beginning
PicInfo init: found 11: [viewz/00D6FB01ABB1()_1_20150225175109_7371.jpg] taken at 2015/02/25 17:51:08
MVC::insertNewObject about to insert Object 11 - http://my.site.perso/00D6FB01ABB1()_1_20150225175109_7371.jpg
configureCell: object#11 not found !?
MVC::insertNewObject successfully inserted Object 11 - http://my.site.perso/00D6FB01ABB1()_1_20150225175109_7371.jpg
MVC::insertNewObject beginning
PicInfo bad packing
init: found 12: [viewz/00626E423E6A()_1_20150225175018_4683.jpg] taken at 2015/02/25 17:50:19
bad packing
bad packing
MVC::insertNewObject about to insert Object 12 - http://my.site.perso/00626E423E6A()_1_20150225175018_4683.jpg
bad packing
MVC::didChangeObject: nil cell at Optional(12)
<UITableView: 0x7fea05030000; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fea0333c180>; layer = <CALayer: 0x7fea03337d90>; contentOffset: 0, -64; contentSize: 320, 572>
MVC::insertNewObject successfully inserted Object 12 - http://my.site.perso/00626E423E6A()_1_20150225175018_4683.jpg
MVC::insertNewObject beginning
PicInfo init: found 13: [viewz/00626E423E6A()_1_20150225175007_4682.jpg] taken at 2015/02/25 17:50:18
MVC::insertNewObject about to insert Object 13 - http://my.site.perso/00626E423E6A()_1_20150225175007_4682.jpg
MVC::insertNewObject successfully inserted Object 13 - http://my.site.perso/00626E423E6A()_1_20150225175007_4bad packing
682.jpg
MVC::insertNewObject beginning
PicInfo init: found 14: [viewz/00626E423E6A()_1_20150225175002_4681.jpg] taken at 2015/02/25 17:50:03
MVC::insertNewObject about to insert Object 14 - http://my.site.perso/00626E423E6A()_1_20150225175002_4681.jpg
MVC::insertNewObject successfully inserted Object 14 - http://my.site.perso/00626E423E6A()_1_20150225175002_4681.jpg
MVC::insertNewObject beginning
PicInfo init: found 15: [viewz/00626E423E6A()_1_20150225174957_4680.jpg] taken at 2015/02/25 17:49:58
MVC::insertNewObject about to insert Object 15 - http://my.site.perso/00626E423E6A()_1_20150225174957_4680.jpg
MVC::insertNewObject successfully inserted Object 15 - http://my.site.perso/00626E423E6A()_1_20150225174957_4680.jpg
MVC::insertNewObject beginning
PicInfo init: found 16: [viewz/00626E423E6A()_1_20150225174952_4679.jpg] taken at 2015/02/25 17:49:52
MVC::insertNewObject about to insert Object 16 - http://my.site.perso/00626E423E6A()_1_20150225174952_4679.jpg
bad packing
MVC::insertNewObject successfully inserted Object 16 - http://my.site.perso/00626E423E6A()_1_20150225174952_4679.jpg
MVC::insertNewObject beginning
bad packing
PicInfo init: found 17: [viewz/00626E423E6A()_1_20150225174946_4678.jpbad packing
g] taken at 2015/02/25 17:49:47
bad packing
bad packing
bad packing
bad packing
MVC::insertNewObject about to insert Object 17 - http://my.site.perso/00626E423E6A()_1_20150225174946_4678.jpg
MVC::didChangeObject: nil cell at Optional(17)
<UITableView: 0x7fea05030000; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fea0333c180>; layer = <CALayer: 0x7fea03337d90>; contentOffset: 0, -64; contentSize: 320, 572>
MVC::didChangeObject: nil cell at Optional(17)
<UITableView: 0x7fea05030000; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fea0333c180>; layer = <CALayer: 0x7fea03337d90>; contentOffset: 0, -64; contentSize: 320, 792>
MVC::insertNewObject successfully inserted Object 17 - http://my.site.perso/00626E423E6A()_1_20150225174946_4678.jpg
MVC::insertNewObject beginning
PicInfo init: found 18: [viewz/00626E423E6A()_1_20150225174941_4677.jpg] taken at 2015/02/25 17:49:42

....snip....

MVC::insertNewObject beginning
PicInfo init: found 23: [viewz/00626E423E6A()_1_20150225174920_4673.jpg] taken at 2015/02/25 17:49:21
MVC::insertNewObject about to insert Object 23 - http://my.site.perso/00626E423E6A()_1_20150225174920_4673.jpg
MVC::insertNewObject successfully inserted Object 23 - http://my.site.perso/00626E423E6A()_1_20150225174920_4673.jpg
MVC::insertNewObject beginning
PicInfo init: found 24: [viewz/QOQA_CAM_UPLOADX_2015022517492001.jpg] taken at 2015/02/25 17:49:20
MVC::insertNewObject about to insert Object 24 - http://my.site.perso/QOQA_CAM_UPLOADX_2015022517492001.jpg
MVC::insertNewObject successfully inserted Object 24 - http://my.site.perso/QOQA_CAM_UPLOADX_2015022517492001.jpg
MVC::insertNewObject beginning
PicInfo init: found 25: [viewz/00D6FB01ABB1()_1_20150225174857_7370.jpg] taken at 2015/02/25 17:48:57
MVC::insertNewObject about to insert Object 25 - http://my.site.perso/00D6FB01ABB1()_1_20150225174857_7370.jpg
MVC::didChangeObject: nil cell at Optional(25)
<UITableView: 0x7fea05030000; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fea0333c180>; layer = <CALayer: 0x7fea03337d90>; contentOffset: 0, -64; contentSize: 320, 1012>

我认为后台获取有点奇怪:它以系统的“找不到对象”消息开始,而漫画哈希汤在最后崩溃时掉落。

我在创建新的托管对象时做错了吗?

【问题讨论】:

您的 tableView 数据源方法在哪里?他们应该从您的获取结果控制器返回行数和节数 感谢您的回答。这是个好问题。我记得删除了关于 sectioncount 的那个(我首先修改为返回 1,但它并没有改变任何结果和错误记录)但我认为 xcode 生成的 mvc swift 文件中没有另一个存在。 在 Interface Builder 中,您能否检查您的 UITableViewdelegatedataSource 属性是否已连接到您的 MasterViewController 您好,感谢您的回复。是的。 这仍然不是崩溃日志。当这停止时,您应该在控制台中看到某种错误。如果您使用的是后台线程,请注意您不能跨线程使用托管对象,但这是另一个问题 【参考方案1】:

您没有实现正确的表视图数据源方法。因为您已对具有方法的基本实现的 UITableViewController 进行了子类化,所以您不会看到警告,但无论您持有什么数据,您都将返回一个部分和零行。

看起来你只有一个部分,所以你可以留下它,但你需要这个方法:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return return (fetchedResultsController?.sections?[section] as? NSFetchedResultsSectionInfo)?.numberOfObjects ?? 0

这给出了一个部分的行数。如果你知道你只会有一个部分,你可以使用

return fetchedResultsController?.fetchedObjects?.count ?? 0

这不那么可怕了。

【讨论】:

IT 崩溃:我明白了: ;W +lHa;y egr = ; ncioznetresn t=O f> ;层 = ;内容偏移:0,-64;内容大小:320, 64856> 它发生在 didChangeContent() 调用期间,在 endUpdates() 处。 这不是崩溃日志,到底发生了什么?看起来复制和粘贴有点奇怪...... 感谢您回复我。我编辑了帖子。有趣的是,当它到达 12 号左右时,它终于找到了对象……他们可能还在下载……【参考方案2】:

从昨天开始我对我的代码做了很多事情,现在它有点工作了:

    将网络摄像头图片存储到临时目录而不是 coredata。我这样做是因为我不知道如何推迟 MOC 保存操作,直到 NSManagedObject 下载了它自己的图片。 我还意识到我不是在处理我的 PicInfo 对象,而是在处理 NSManaged 对象。然后我编写了一些桥接程序,以便从 PI 对象中获取 MO,反之亦然。

【讨论】:

以上是关于使用 Coredata 学习 Swift:为啥我没有得到任何 UITableViewCells?的主要内容,如果未能解决你的问题,请参考以下文章

CoreData学习:Core Data Stack(Swift)

CoreData - 创建新实体 - 为啥不需要保存它?

iOS CoreData 增删改查详解

为啥我的视图控制器没有检索到我的 CoreData 对象

使用 Swift 过滤 UISearchBar 的核心数据

iOS swift:使用 coredata (cloudkit) 存储缓存