[英]Error :Use of 'self' in property access 'content' before self.init initializes self
I've seen all the problems with keyword Use of 'self' in property
but still couldn't solve it. 我已经看到关键字Use of 'self' in property
所有问题,但仍然无法解决。 I just started learning swift 3.01 and my Xcode version is 8.2. 我刚刚开始学习Swift 3.01,而我的Xcode版本是8.2。 Please help me! 请帮我!
I was changing the app Apple provided . 我正在更改Apple提供的应用程序 。
I want to create a textView
so users can type text and store it. 我想创建一个textView
以便用户可以输入文本并将其存储。 While I was changing the Meal.swift
, I got the error: Error :Use of 'self' in property access 'content' before self.init initializes self
just at the end of the code: 当我更改Meal.swift
,出现错误: Error :Use of 'self' in property access 'content' before self.init initializes self
在代码末尾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
}
}
Please help me to find up the what's wrong in there, Best regard! 请帮助我找到那里的问题,最好的问候!
You have to decode content
, too 您也必须解码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)
}
By the way: guard
ing values in encode
/ decode
methods reveals developer / design errors. 顺便说一句:在encode
/ decode
方法中guard
值会揭示开发人员/设计错误。 Nobody else but the application can create those objects and you are supposed to know that the value does exist. 除了应用程序之外,没有其他人可以创建这些对象,并且您应该知道该值确实存在。 You must not guard
to catch runtime errors which should actually never occur. 你不能guard
赶上这实际上应该不会发生运行时错误。
I've solved my problem add let content = content.text
in MealViewController
's func prepare
我已经解决了我的问题,在MealViewController
的func prepare
添加let content = content.text
It's totally looks like that : 看起来就像这样:
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!)
}
Just give everyone to be a referance. 只是给大家一个参考。 Hope you will enjoy. 希望你会喜欢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.