- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我一定是错误地使用了 NSUserDefaults 的自定义对象。错误“属性列表对格式无效:200(属性列表不能包含‘CFType’类型的对象)”。下面是我的代码,Goal 类特别有趣,因为这是我采用 NSCoding 协议(protocol)的地方。
此代码是全局的。
func saveGoals (goals : [Goal]) {
var updatedGoals = NSKeyedArchiver.archivedDataWithRootObject(goals)
NSUserDefaults.standardUserDefaults().setObject(updatedGoals, forKey: "Goals")
NSUserDefaults.standardUserDefaults().synchronize()
}
func loadCustomObjectWithKey() -> [Goal] {
if let encodedObject : NSData = NSUserDefaults.standardUserDefaults().objectForKey("Goals") as? NSData {
var encodedObject : NSData? = NSUserDefaults.standardUserDefaults().objectForKey("Goals") as? NSData
var goal : [Goal] = NSKeyedUnarchiver.unarchiveObjectWithData(encodedObject!) as [Goal]
return goal
} else {
return [Goal]()
}
}
这段代码在 GoalsViewController 中。
class GoalsViewController: MainPageContentViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: GoalsTableView!
var cell = GoalTableViewCell()
var goalsArray : Array<Goal> = [] //
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
if var storedGoals: [Goal] = loadCustomObjectWithKey() as [Goal]? {
goalsArray = storedGoals
}
//retrieve data.
var goal = Goal(title: "Walk the Dog")
goalsArray.append(goal)
saveGoals(goalsArray)
self.tableView?.reloadData()
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
var notification = NSNotificationCenter.defaultCenter()
notification.addObserver(self, selector: "finishCreatingGoal:", name: "FinishCreatingGoal", object: nil)
}
func finishCreatingGoal(notification : NSNotification) {
if (notification.name == "FinishCreatingGoal") {
var userInfo = notification.userInfo!
var text = userInfo["text"]! as String
var index = userInfo["index"]! as Int
var cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: index, inSection: 0)) as GoalTableViewCell
goalsArray[index].title = cell.goalTextField.text
saveGoalList(goalsArray)
self.tableView.reloadData()
self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: index, inSection: 0), atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
}
}
此代码在目标类中。
import UIKit
class Goal : NSObject, NSCoding {
var title : String? = ""
var checkmarked : Bool? = false
var isLastCell : Bool? = false
var enabled : Bool? = true
var priority = Priority.defaultPriority
override init() {
}
init(title : String) {
self.title = title
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(title!, forKey: "title")
aCoder.encodeBool(checkmarked!, forKey: "checkmarked")
aCoder.encodeBool(isLastCell!, forKey: "isLastCell")
aCoder.encodeBool(enabled!, forKey: "enabled")
}
required init(coder aDecoder: NSCoder) {
title = aDecoder.decodeObjectForKey("title") as String!
checkmarked = aDecoder.decodeBoolForKey("checkmarked") as Bool
isLastCell = aDecoder.decodeBoolForKey("isLastCell") as Bool
enabled = aDecoder.decodeBoolForKey("enabled") as Bool
}
}
最佳答案
我打算从我的工作项目中复制代码:
这是带有数学抽认卡游戏数据的游戏对象类:
import Foundation
class GameData: NSObject {
var sign: String = "+"
var level: Int = 1
var problems: Int = 10
var time: Int = 30
var skipWrong: Bool = true
var usedTime: Int = 0
var correctCount: Int = 0
var correctTopNumber: [Int] = [Int]()
var correctBottomNumber: [Int] = [Int]()
var wrongTopNumber: [Int] = [Int]()
var wrongBottomNumber: [Int] = [Int]()
var date: NSDate = NSDate()
func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeObject(sign, forKey: "sign")
aCoder.encodeInteger(level, forKey: "level")
aCoder.encodeInteger(problems, forKey: "problems")
aCoder.encodeInteger(time, forKey: "time")
aCoder.encodeBool(skipWrong, forKey: "skipWrong")
aCoder.encodeInteger(usedTime, forKey: "usedTime")
aCoder.encodeInteger(correctCount, forKey: "correctCount")
aCoder.encodeObject(correctTopNumber, forKey: "correctTopNumber")
aCoder.encodeObject(correctBottomNumber, forKey: "correctBottomNumber")
aCoder.encodeObject(wrongTopNumber, forKey: "wrongTopNumber")
aCoder.encodeObject(wrongBottomNumber, forKey: "wrongBottomNumber")
aCoder.encodeObject(date, forKey: "date")
}
init(coder aDecoder: NSCoder!) {
sign = aDecoder.decodeObjectForKey("sign") as String
level = aDecoder.decodeIntegerForKey("level")
problems = aDecoder.decodeIntegerForKey("problems")
time = aDecoder.decodeIntegerForKey("time")
skipWrong = aDecoder.decodeBoolForKey("skipWrong")
usedTime = aDecoder.decodeIntegerForKey("usedTime")
correctCount = aDecoder.decodeIntegerForKey("correctCount")
correctTopNumber = aDecoder.decodeObjectForKey("correctTopNumber") as Array
correctBottomNumber = aDecoder.decodeObjectForKey("correctBottomNumber") as Array
wrongTopNumber = aDecoder.decodeObjectForKey("wrongTopNumber") as Array
wrongBottomNumber = aDecoder.decodeObjectForKey("wrongBottomNumber") as Array
date = aDecoder.decodeObjectForKey("date") as NSDate
}
override init() {
}
}
这部分看起来和你的差不多,但是有更多的变量类型。归档器和检索器类与您不同:
import Foundation
class ArchiveGameData:NSObject {
var documentDirectories:NSArray = []
var documentDirectory:String = ""
var path:String = ""
func ArchiveResults(#dataSet: [GameData]) {
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("results3.archive")
if NSKeyedArchiver.archiveRootObject(dataSet, toFile: path) {
//println("Success writing to file!")
} else {
println("Unable to write to file!")
}
}
func RetrieveGameData() -> NSObject {
var dataToRetrieve = [GameData]()
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("results3.archive")
if let dataToRetrieve2 = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? [GameData] {
dataToRetrieve = dataToRetrieve2
}
return(dataToRetrieve)
}
}
最后,用于在 ViewController 中存储和检索的代码:
//retrieveing
var gameDataArray = ArchiveGameData().RetrieveGameData() as [GameData]
//Archiving
gameData = GameData() //create local object then append all the new data, then store it
gameData.sign = buttonStates.sign
gameData.level = buttonStates.level
gameData.problems = buttonStates.problems
gameData.time = buttonStates.time
//etc. for all properties
ArchiveGameData().ArchiveResults(dataSet: gameDataArray)
关于ios - NSUserDefaults 自定义对象 - 格式 : 200 (property lists cannot contain objects of type 'CFType' ) 的属性列表无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26174989/
我有一个在 ARC (DTCoreText) 上运行的项目,我想在 UIFont 上实现一个返回匹配的 CTFontRef 的类别方法。这是我目前所拥有的: @implementation UIFon
是否可以创建不是从 CFTypeRef 派生的不透明类型,可以使用 CFRetain/CFRelease 保留/释放?或者如何从 CFType 派生新类型? 最佳答案 我从未这样做过,但可以使用私有(
我们正在努力使固定数组(及其所有固定组件,在多个级别)可变,似乎唯一的方法是遍历嵌套固定数组中的所有级别并创建使用 arrayWithArray 或 mutableCopy 的可变对象。 做一些研究我
有人可以帮我转换下面的代码以支持 ARC 吗? UIFont *boldFont = [UIFont fontWithName:@"DINPro-Medium" size:14]; CTFontRef
简而言之:如何在运行时确定id 是否为CFType 我正在实现 dynamic core data attributes在 ExtendedManagedObject 的 willSave 方法中,我
我希望能够在每次特定的 CFType 时记录消息(最好是中断调试器)对象(对于我目前的目的,一个 CGPDFDocument )被分配、保留、释放或释放。 因为没有 Create...() CGPDF
我在使用 Core Foundation 类型和集合方面的经验有限,所以如果这很明显,我深表歉意。 我正在使用 CFBitVector 类型来存储一些位序列,并且我需要将其存储为二进制数据格式(以便可
我一定是错误地使用了 NSUserDefaults 的自定义对象。错误“属性列表对格式无效:200(属性列表不能包含‘CFType’类型的对象)”。下面是我的代码,Goal 类特别有趣,因为这是我采用
我是一名优秀的程序员,十分优秀!