我已经看到了关键字Use of 'self' in property
的所有问题但还是解决不了。我刚开始学习swift 3.01,我的Xcode版本是8.2。请帮帮我!
我正在更改苹果提供的应用程序。
我想创建一个textView
以便用户可以键入文本并存储它。当我更改Meal.swift
时,我收到错误: Error :Use of 'self' in property access 'content' before self.init initializes self
在代码的末尾:
import UIKit
import os.log
class Meal: NSObject, NSCoding {
//MARK: Properties
var name: String
var photo: UIImage?
var content: String
//MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
//MARK: Types
struct PropertyKey {
static let name = "name"
static let photo = "photo"
static let content = "content"
}
//MARK: Initialization
init?(name: String, photo: UIImage?, content: String) {
// The name must not be empty
guard !name.isEmpty else {
return nil
}
// The content must not be empty
guard !content.isEmpty else {
return nil
}
// Initialize stored properties.
self.name = name
self.photo = photo
self.content = content
}
//MARK: NSCoding
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.name)
aCoder.encode(photo, forKey: PropertyKey.photo)
aCoder.encode(content, forKey: PropertyKey.content)
}
required convenience init?(coder aDecoder: NSCoder) {
// The name is required. If we cannot decode a name string, the initializer should fail.
guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
os_log("Unable to decode the name for a Meal object.", log: OSLog.default, type: .debug)
return nil
}
// Because photo is an optional property of Meal, just use conditional cast.
let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage
// Must call designated initializer.
self.init(name: name, photo: photo, content: content)// Error happened to here by this : Error :Use of 'self' in property access 'content' before self.init initializes self
}
}
请帮我找出那里的问题,最好的问候!
你也必须解码content
required convenience init?(coder aDecoder: NSCoder) {
// The name is required. If we cannot decode a name string, the initializer should fail.
let name = aDecoder.decodeObject(forKey: PropertyKey.name) as! String
// Because photo is an optional property of Meal, just use conditional cast.
let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage
let content = aDecoder.decodeObject(forKey: PropertyKey.content) as! String
// Must call designated initializer.
self.init(name: name, photo: photo, content: content)
}
顺便说一句:guard
encode
/decode
方法中的值会揭示开发人员/设计错误。除了应用程序之外,没有其他人可以创建这些对象,您应该知道该值确实存在。您不得guard
捕获实际上永远不会发生的运行时错误。
我已经解决了我的问题,在MealViewController
的func prepare
中添加let content = content.text
它完全看起来像:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
// Configure the destination view controller only when the save button is pressed.
guard let button = sender as? UIBarButtonItem, button === saveButton else {
os_log("The save button was not pressed, cancelling", log: OSLog.default, type: .debug)
return
}
let name = nameTextField.text ?? ""
let photo = photoImageView.image
let content = content.text // Add this new code.
// Set the meal to be passed to MealTableViewController after the unwind segue.
meal = Meal(name: name, photo: photo, content: content!)
}
只要让每个人都成为参考。希望你会喜欢。