核心数据:应用程序在访问NSManagedObject属性时崩溃
我描述了这个问题。 我有一个CoreData实体“New”。 我正在使用带有tableView的fetchedResultsController来呈现对象。 问题是,当应用程序尝试更新标签时,它崩溃了(单元格有两个标签,但是应用程序总是在同一个句子中崩溃,更新相同的标签……)。
一些代码在这里:
- 这是CoreDataManager的定义:
{
// MARK: - Shared Instance /** * This class variable provides an easy way to get access * to a shared instance of the CoreDataStackManager class. */ class func sharedInstance() -> CoreDataStackManager { struct Singleton { static let instance = CoreDataStackManager() } return Singleton.instance } // MARK: - The Core Data stack. The code has been moved, unaltered, from the AppDelegate. lazy var applicationDocumentsDirectory : NSURL = { let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) return urls[urls.count-1] }() lazy var managedObjectModel: NSManagedObjectModel = { let modelURL = NSBundle.mainBundle().URLForResource("Model", withExtension: "momd")! return NSManagedObjectModel(contentsOfURL: modelURL)! }() lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = { let coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent(SQLITE_FILE_NAME) var failureReason = "There was an error creating or loading the application's saved data." do { try coordinator?.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil) } catch { // Report any error we got. var dict = [String: AnyObject]() dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" dict[NSLocalizedFailureReasonErrorKey] = failureReason dict[NSUnderlyingErrorKey] = error as NSError let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) // Replace this 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. NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)") abort() } return coordinator }() lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }() // MARK: - Core Data Saving support func saveContext() { if managedObjectContext.hasChanges { managedObjectContext.performBlockAndWait { do { try self.managedObjectContext.save() } catch { let nserror = error as NSError NSLog("Unresolved error \(nserror), \(nserror.userInfo)") abort() } } }
-
这里,应用崩溃的地方:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("HotNewsCell") as! NewsTableViewCell let new = fetchedResultsController.objectAtIndexPath(indexPath) as! New configureCell(cell, new: new) return cell } private func configureCell(cell: NewsTableViewCell, new: New) { cell.titleLabel.text = new.title /* Next line is where app crashes :( */ cell.descriptionLabel.text = new.newBody if let url = NSURL(string: new.photoReference) { cell.activityIndicator.startAnimating() if new.image != nil { cell.imageViewNews.image = new.image cell.activityIndicator.stopAnimating() } else { let task = NetworkRequests.sharedInstance().makeImageRequestFromURL(url) { (data, error) in guard error == nil else { print(error) return } guard let data = data else { print("No data available") return } let image = UIImage(data: data) new.image = image dispatch_async(dispatch_get_main_queue()) { cell.imageViewNews.image = image cell.activityIndicator.stopAnimating() } } cell.taskToCancelifCellIsReused = task } }
这很奇怪,因为如果我评论“cell.descriptionLabel.text = new.newBody”,应用程序就可以完美运行。
谢谢!
编辑
错误是EXC_BAD_ACCESS。 然后,我启用了NSZombie,错误是“消息发送到解除分配的实例”。
我相信这是一个使用属性名称的人工制品,它开始了new....
要避免此问题,只需更改属性的名称即可。
另见这个无关问题的答案 ,它突出了new...
问题new...
从该答案中确定的文件 (Clang文档),从技术上讲,如果“new”之后的字符是小写字母,则不会出现问题。 所以newbody
会好的,而newBody
却不行。 此外,为了完整性,同样应避免使用以下前缀(尽管它们不太可能是属性名称的选择):
- ALLOC
- 复制
- mutableCopy
- 在里面
有趣的是,Xcode(至少版本7.3;不确定以前的版本)将不允许在Objective-C中使用这些属性名称,从而产生编译器错误:
属性遵循返回“拥有”对象的Cocoa命名约定
遗憾的是,Swift编译器不会给出任何错误或警告。