意外在UITableViewController中发现nil

时间:2019-03-19 16:04:59

标签: swift uitableview core-data

我正在尝试在UITableViewController中获取核心数据对象,但出现致命错误。有趣的是,该日志实际上在底部显示了该值,但应用程序stil崩溃了

import UIKit
import CoreData
import MediaPlayer

class FavoritesTableViewController: UIViewController, NSFetchedResultsControllerDelegate, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!
var entry: Song?
var song: MPMediaItem!
var songs: [Song?] = []
//    var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!

override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.tableView.dataSource = self
    self.tableView.delegate = self
    self.initializeFetchRequest()
    self.tableView.reloadData()

    self.tableView.tableFooterView = UIView(frame: CGRect.zero)

}


func initializeFetchRequest() {

    let coreDataStack: CoreDataStack = CoreDataStack.defaultStack
    let fetchRequest: NSFetchRequest = self.entryListFetchRequest()

    //        self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    coreDataStack.managedObjectContext.performAndWait {
        do {
            if #available(iOS 10.0, *) {
                self.songs = try fetchRequest.execute() as? [Song] ?? []
            } else {
                // Fallback on earlier versions
                self.songs = try coreDataStack.managedObjectContext.fetch(fetchRequest) as? [Song] ?? []
            }
        } catch {
            print(error)
        }
    }

    //        fetchedResultsController.delegate = self
    //
    //        do {
    //            try self.fetchedResultsController.performFetch()
    //        } catch {
    //            print(error)
    //        }

}

func entryListFetchRequest() -> NSFetchRequest<NSFetchRequestResult> {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Song")

    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]

    return fetchRequest
}

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

// MARK: - Table view data source

func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    let newSongs = songs.compactMap{ $0 }
    print(newSongs.map{$0.songId})
    if (newSongs.count > 0) {
        return newSongs.count
    } else {
        return 0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    let newSongs = self.songs.compactMap{ $0 }
    self.entry = newSongs[indexPath.row]
    if let currentEntry = self.entry {
        if (currentEntry.songId != nil) {
            print("Hello", currentEntry.songId!)
            self.song = findSongWithPersistentIdString(persistentIDString: currentEntry.songId!)
            // Configure the cell...
            cell.textLabel?.text = self.song.value(forKey: MPMediaItemPropertyTitle) as? String
        }
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

    // Configure the cell...

    self.tableView.deselectRow(at: indexPath, animated: true)

    self.entry = songs[indexPath.row]
    if let currentEntry = self.entry {
        print("Hello", currentEntry.songId!)
        self.song = findSongWithPersistentIdString(persistentIDString: currentEntry.songId!)
        // Configure the cell...
    }


    self.performSegue(withIdentifier: "details", sender: self)
}

func findSongWithPersistentIdString(persistentIDString: String) -> MPMediaItem? {
    let predicate = MPMediaPropertyPredicate(value: persistentIDString, forProperty: MPMediaItemPropertyPersistentID)
    let songQuery = MPMediaQuery()
    songQuery.addFilterPredicate(predicate)

    var song: MPMediaItem?
    if let items = songQuery.items, items.count > 0 {
        song = items[0]
    }
    return song
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "details") {
//            let navController: UINavigationController = segue.destination as! UINavigationController
        let entryVC: SongDetailsViewController = segue.destination as! SongDetailsViewController
        entryVC.entry = entry
        entryVC.song = self.song
    }
}
}

print命令实际上会打印日志,但是应用程序崩溃。

以下是我访问核心数据的方式

    func initializeFetchRequest() {

    let coreDataStack: CoreDataStack = CoreDataStack.defaultStack
    let fetchRequest: NSFetchRequest = self.entryListFetchRequest()

    //        self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    coreDataStack.managedObjectContext.performAndWait {
        do {
            if #available(iOS 10.0, *) {
                self.songs = try fetchRequest.execute() as? [Song]
            } else {
                // Fallback on earlier versions
                self.songs = try coreDataStack.managedObjectContext.fetch(fetchRequest) as? [Song]
            }
        } catch {
            print(error)
        }
    }

    //        fetchedResultsController.delegate = self
    //
    //        do {
    //            try self.fetchedResultsController.performFetch()
    //        } catch {
    //            print(error)
    //        }

}

func entryListFetchRequest() -> NSFetchRequest<NSFetchRequestResult> {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Song")

    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]

    return fetchRequest
}

实际上,我正在将喜欢的歌曲保存在屏幕中,然后从那里尝试打开存在上述代码的“喜欢的屏幕”。

0 个答案:

没有答案