核心数据导致 iPhone 崩溃

Posted

技术标签:

【中文标题】核心数据导致 iPhone 崩溃【英文标题】:Core data is causing the iPhone crash 【发布时间】:2018-09-24 07:21:41 【问题描述】:

将数据保存到核心数据上没有问题。 我的问题在于我应该获取数据的那个 vc。

核心数据

@objc(ItemInCard)
public class ItemInCard: NSManagedObject 


获取

let fetchRequest : NSFetchRequest<ItemInCard> = ItemInCard.fetchRequest()
    do
    
        let itemIncard = try  PersistanceService.context.fetch(fetchRequest)
        self.item = itemIncard
        self.Tableview.reloadData()
    
    catch
    

    

表格视图

var item = [ItemInCard]()
    //MARK: - Table view
func numberOfSections(in tableView: UITableView) -> Int 
    return 1

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    print("=======")
    print(item)
    return item.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "ShoppingCardCell") as? ShppingCellCustomTableViewCell


    cell!.textLabel?.text = item[indexPath.row].productTitleCore

    self.Tableview.reloadData()
    return cell!

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return 180

只要该 vc 在应用程序中打开,它就会打印核心数据(我添加了打印以检查发生了什么

它不断打印下面的核心数据

[<ItemInCard: 0x281a4efd0> (entity: ItemInCard; id: 0x87c125f9e2c25dff <x-coredata://139AE9B3-30B6-4857-8313-456481AF833C/ItemInCard/p1> ; data: 
    paymentTypeCore = "\U0648\U0627\U0631\U064a\U0632\U064a";
    priceCore = 10000;
    priceTypeCore = "\U0639\U0627\U062f\U06cc-test";
    productTitleCore = "\U062c\U0648 \U0627\U06a9\U0631\U0627\U06cc\U0646 \U0628\U0646\U062f \U0627\U0645\U0627\U0645 \U062a\U062d\U0648\U06cc\U0644 \U0645\U0647\U0631\U

但我的应用中只有一个数据。表格也没有填充

【问题讨论】:

Offtopic:将 TableView 重命名为 tableView 并将“as?ShppingCellCustomTableViewCell”更改为“as!ShppingCellCustomTableViewCell” 【参考方案1】:

从 cellForRowAt 方法中移除对 reloadData 的调用。当应用需要重新加载 tableView 时调用 cellForRowAt。实际上,您是在告诉它在创建每个单元格后开始重新加载,这样您就永远不会超过第一个单元格。这解释了为什么您只能看到一项。

【讨论】:

【参考方案2】:

你什么时候打电话给var item = [ItemInCard]()

如果

let fetchRequest : NSFetchRequest<ItemInCard> = ItemInCard.fetchRequest()

之前调用
var item = [ItemInCard]()

那么你就发现了你的问题。

self.item = itemIncard 之后调用var item = [ItemInCard]() 将创建一个新实例并否定放入self.item 的任何内容。

同时发布 item.count 返回的内容,以进一步帮助您解决问题。快乐编码!

【讨论】:

var item = [ItemInCard]() 创建一个 ItemInCard 类型的空数组 var item = [ItemInCard]() 是我在vc中声明的第一件事 当我将数据保存到核心数据时,我也会这样做:: vc.item.append(itemInCard) 你能发布item.count返回的内容吗?【参考方案3】:

不要在cellForRowAt 方法中调用tableView.reloadData()。因为它会导致 tableView 在每次尝试加载单元格时重新加载。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "ShoppingCardCell") as? ShppingCellCustomTableViewCell


    cell!.textLabel?.text = item[indexPath.row].productTitleCore

    //Remove or comment this line self.Tableview.reloadData()
    self.Tableview.reloadData()
    return cell!

【讨论】:

以上是关于核心数据导致 iPhone 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

从 iphone 的核心数据中删除对象时应用程序崩溃

iOS核心数据在后台获取导致崩溃

iPhone - 将核心数据添加到现有项目?

使用 RestKit 导致核心数据崩溃的多个 RKResponseDescriptor

试图设置核心数据关系导致崩溃

从大型 JSON 加载核心数据导致应用程序崩溃