gpt4 book ai didi

ios - 滚动 UITableView 时,NSManagedObject 数组变为 nil

转载 作者:行者123 更新时间:2023-11-28 15:30:04 26 4
gpt4 key购买 nike

我的应用程序中有一个 ViewController,我必须在其中向用户显示设置,用户可以使用 UISwitch 打开或关闭设置。我必须将设置存储在本地数据库中,并根据该显示数据在应用程序中向用户显示。

我正在使用 SugarRecord 进行核心数据管理。最初所有的设置都是打开的。

SugarRecordManager.swift

import Foundation
import SugarRecord
import CoreData


class SugarRecordManager
{
static let sharedInstance = SugarRecordManager()
private init(){

}

// Initializing CoreDataDefaultStorage
func coreDataStorage() -> CoreDataDefaultStorage {
let store = CoreDataStore.named("db")
let bundle = Bundle(for: type(of: self))
let model = CoreDataObjectModel.merged([bundle])
let defaultStorage = try! CoreDataDefaultStorage(store: store, model: model)
return defaultStorage
}

//MARK:- User Settings methods

//update local settings
func updateSettingsModel(userSettings: [UserSetting]){
let db = self.coreDataStorage()
for localSetting in userSettings{
try! db.operation { (context, save) -> Void in
if let settingObjectToUpdate = try! context.request(UserSetting.self).filtered(with: "groupName", equalTo: localSetting.groupName!).fetch().first{
settingObjectToUpdate.groupId = localSetting.groupId! as String
settingObjectToUpdate.groupName = localSetting.groupName! as String
settingObjectToUpdate.isGroupActive = localSetting.isGroupActive
try! context.insert(settingObjectToUpdate)
save()

}
}
}
}

//retrieve settings from storage
func getAllSettings() -> [UserSetting] {
let db = self.coreDataStorage()
var userSettings : [UserSetting]
do {
userSettings = try db.fetch(FetchRequest<UserSetting>())
} catch {
userSettings = []
}
return userSettings
}

//initialise settings for the first time
func initialiseUserSettings(){
let db = self.coreDataStorage()
var groupNameArray = UserDefaults.standard.value(forKey: "groupNamesArrayKey") as? [String]
var groupIdArray = UserDefaults.standard.value(forKey: "groupIdsArrayKey") as? [String]
for i in 0 ..< groupIdArray!.count {
try! db.operation { (context, save) -> Void in
let settingObject: UserSetting = try! context.new()
settingObject.groupId = groupIdArray?[i];
settingObject.groupName = groupNameArray?[i];
settingObject.isGroupActive = true;
try! context.insert(settingObject)
save()
}
}
}
}

SettingsViewController.swift

class SettingsViewController: BaseViewController, UITableViewDataSource, UITableViewDelegate, SettingsCellDelegate {

@IBOutlet weak var btnSideNav: UIBarButtonItem!

@IBOutlet weak var settingsTable: UITableView!

var userSetting = [UserSetting]() //array to hold settings from storage

override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false;
btnSideNav.target = revealViewController();
btnSideNav.action = #selector(SWRevealViewController.revealToggle(_:));
userSetting = SugarRecordManager.sharedInstance.getAllSettings() //here userSetting contains data and I have checked it
self.settingsTable.reloadData()
self.settingsTable.dataSource = self;
self.settingsTable.delegate = self;
// Do any additional setup after loading the view.
}

//MARK:- Table View Methods

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("Count of cells = \(self.userSetting.count)") //prints 18 which is good
return self.userSetting.count
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60;
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let settingsCell : SettingsCell? = tableView.dequeueReusableCell(withIdentifier: "SettingsCell") as? SettingsCell;
settingsCell?.setUpWithModel(model: self.userSetting[indexPath.row], cell: settingsCell!)
settingsCell?.delegate = self as SettingsCellDelegate;
return settingsCell!
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}


func didTappedSwitch(cell: SettingsCell) {
let indexPath = settingsTable.indexPath(for: cell);
userSetting[(indexPath?.row)!].isGroupActive? = cell.isGroupActive.isOn as NSNumber
}

@IBAction func btnSaveTapped(_ sender: UIButton) {
// code to save settings
}
}

SettingsCell.swift

protocol SettingsCellDelegate {
func didTappedSwitch(cell: SettingsCell)
}

class SettingsCell: UITableViewCell {

@IBOutlet weak var groupName: UILabel!

@IBOutlet weak var lblGroupId: UILabel!
@IBOutlet weak var isGroupActive: UISwitch!
var delegate: SettingsCellDelegate!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)

// Configure the view for the selected state
}

func setUpWithModel(model: UserSetting, cell: SettingsCell)
{
cell.groupName.text = model.groupName;
cell.lblGroupId.text = model.groupId;
isGroupActive.setOn((model.isGroupActive?.boolValue)!, animated: false)
}


@IBAction func isGroupActiveValueChanged(_ sender: UISwitch) {
delegate.didTappedSwitch(cell: self)

}

}

现在,最初填充了 TableView,并且所有数组都工作正常,但是一旦我滚动 TableView,所有数据都消失了。甚至 userSetting 数组也是空的。我知道这与上下文有关,但无法弄清楚是什么。任何帮助将不胜感激。

最佳答案

像这样更改您的 func coreDataStorage() -> CoreDataDefaultStorage

// Initializing CoreDataDefaultStorage
lazy var coreDataStorage: CoreDataDefaultStorage = {
let store = CoreDataStore.named("db")
let bundle = Bundle(for: type(of: self))
let model = CoreDataObjectModel.merged([bundle])
let defaultStorage = try! CoreDataDefaultStorage(store: store, model: model)
return defaultStorage
}()

你有这个问题是因为你每次做任何请求时都重新初始化 CoreDataDefaultStorage

在你让它变得惰性之后——你将只有一个 CoreDataDefaultStorage 用于整个应用程序生命周期

基本上,将coreDataStorage做成singleton会很好

关于ios - 滚动 UITableView 时,NSManagedObject 数组变为 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44821248/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com