错误:在 self.init 初始化 self 之前在属性访问'content'中使用'self'



我已经看到了关键字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捕获实际上永远不会发生的运行时错误。

我已经解决了我的问题,在MealViewControllerfunc 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!)
}

只要让每个人都成为参考。希望你会喜欢。

最新更新