当我试图运行int(编码器:)它显示此错误时,我不知道为什么? "不可用的初始化程序要求init(编码器:)无法通过可用的初始化程序来满足(' init?')"
class Note: NSObject, NSCoding {
var name: String
var photo: UIImage?
var rating: Int
static let DocumentsDirectory: AnyObject = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
static let ArchiveURL = DocumentsDirectory.URLByAppendingPathComponent("notes")
struct PropertyKey {
static let nameKey = "name"
static let photoKey = "photo"
static let ratingKey = "rating"
}
init?(name: String, photo: UIImage?, rating: Int) {
self.name = name
self.photo = photo
self.rating = rating
super.init()
// Initialization should fail if there is no name or if the rating is negative.
if name.isEmpty || rating < 0 {
return nil
}
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: PropertyKey.nameKey)
aCoder.encodeObject(photo, forKey: PropertyKey.photoKey)
aCoder.encodeInteger(rating, forKey: PropertyKey.ratingKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
// Because photo is an optional property of Meal, use conditional cast.
let photo = aDecoder.decodeObjectForKey(PropertyKey.photoKey) as? UIImage
let rating = aDecoder.decodeIntegerForKey(PropertyKey.ratingKey)
// Must call designated initializer.
self.init(name: name, photo: photo, rating: rating)
}
}
我正在使用xcode 6,顺便说一下,当这段代码在xcode 7中运行时,它没有显示任何错误,原因是什么?
答案 0 :(得分:1)
所以我找到了一种让它工作的方法,即初始化(编码器:)&#39;方法无法实现,所以我所做的就是覆盖&#39; init()&#39; “初始化”(编码器:)&#39;方法,因为它需要调用&#39; self.init()&#39;。所以这是代码:
class Meal: NSObject, NSCoding {
// MARK: Archiving Paths
static let DocumentsDirectory = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
static let ArchiveURL = DocumentsDirectory.URLByAppendingPathComponent("meals")
// MARK: Properties
var name: String
var rating: Int
var photo: UIImage?
// MARK: Types
struct PropertyKey {
static let nameKey = "name"
static let photoKey = "photo"
static let ratingKey = "rating"
}
// MARK: Initialization
init? (name: String, rating: Int, photo: UIImage?) {
// Intialize stored properties.
self.name = name
self.rating = rating
self.photo = photo
super.init()
// Initialization should fail if there is no name or if the rating is negative.
if self.name.isEmpty || (rating < 0) {
return nil
}
}
override private init () {
self.name = ""
self.rating = 0
self.photo = nil
}
// MARK: NSCoding
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.name, forKey: PropertyKey.nameKey)
aCoder.encodeObject(self.photo, forKey: PropertyKey.photoKey)
aCoder.encodeObject(self.rating, forKey: PropertyKey.ratingKey)
}
convenience required init(coder aDecoder: NSCoder) {
self.init()
let name = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
if let rating = aDecoder.decodeIntegerForKey(PropertyKey.ratingKey) {
self.rating = rating
}
// Because photo is an optional property of Meal, use conditional cast.
let photo = aDecoder.decodeObjectForKey(PropertyKey.photoKey) as? UIImage
self.name = name
self.photo = photo
}
}
我制作了&#39; init()&#39;方法private,这样只有类中的方法才能调用它。 我还必须打开评级,因为应用程序崩溃抱怨无法使用ratingKey取消归档Int。
答案 1 :(得分:0)
关于细节的猜测,但是,一般来说 - Swift的精确语法和语义在Xcode 6(比如Xcode 6.4)和新的Xcode 7 beta之间发生了显着的变化。 Xcode 6.4支持/使用Swift语言版本1.2; Xcode 7使用Swift语言版本2.0(beta)
答案 2 :(得分:0)
找到一个在xcode6上运行上面代码的解决方案,应该从init(编码器aDecoder)中删除“方便”并使用super.init()而不是self.init(名称:name,photo:photo,rating:rating)然后它完美地运作
class Note: NSObject, NSCoding {
var name: String
var photo: UIImage?
var rating: Int
struct PropertyKey {
static let nameKey = "name"
static let photoKey = "photo"
static let ratingKey = "rating"
}
init(name: String, photo: UIImage?, rating: Int) {
self.name = name
self.photo = photo
self.rating = rating
super.init()
// Initialization should fail if there is no name or if the rating is negative.
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(name, forKey: PropertyKey.nameKey)
aCoder.encodeObject(photo, forKey: PropertyKey.photoKey)
aCoder.encodeInteger(rating, forKey: PropertyKey.ratingKey)
}
required init(coder aDecoder: NSCoder) {
self.name = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
// Because photo is an optional property of Meal, use conditional cast.
self.photo = aDecoder.decodeObjectForKey(PropertyKey.photoKey) as? UIImage
self.rating = aDecoder.decodeIntegerForKey(PropertyKey.ratingKey) as Int
// Must call designated initializer.
super.init()
}
}