当UITableView滚动时,NSManagedObject Array变为零
我的应用程序中有一个ViewController,我必须向用户显示设置,用户可以使用UISwitch打开或关闭设置。我必须将设置存储在本地数据库中,并基于应用程序中的用户显示数据。当UITableView滚动时,NSManagedObject Array变为零
我正在使用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)
}
}
现在,initally的TableView中填充和所有阵列一旦工作正常,但当我滚动TableView时,所有数据都消失了。即使userSetting数组也是nill。我知道这与上下文有关,但无法弄清楚。任何帮助将不胜感激。
更改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
当你做任何要求,你有这个问题
。
后你做它lazy
- 你将有只有一个CoreDataDefaultStorage
所有应用程序生命
基本上,这将是很好使coreDataStorage
为singleton
首先,您不能对计算属性使用lazy。其次,即使我将coreDataStorage作为计算属性或使其成为单例,它也没有任何影响。 –
使它不是一个计算属性,但使用初始化使其惰性属性,如我的示例中所示:'lazy var coreDataStorage:CoreDataDefaultStorage = {// init code here()' 其实您可以复制粘贴我的示例 –
像魅力一样工作:D非常感谢你! –
你能提供SugarRecordManager类? –
我编辑了问题并添加了SugarRecordManager.swift的代码 –