Swift Cannot assign to self in a method

狂风中的少年 提交于 2019-12-07 13:13:35

问题


I've just faced a strange problem

I have a class called Letter

class Letter
{    
    init() {}
}

And I have an extension for this class:

extension Letter
{
    convenience init(file_path:String) { self = Letter.loadFromFile(file_path)}
    class func loadFromFile(file_path:String)->Letter {...}
}

I need to create and init with path to file and when i call Letter(file_path) I need a new object that returned by a func loadFromFile. How to assign in an init method or to return a new object?

//Edit The same problem...


回答1:


Class functions that return instances of that class seems to be an anti-pattern in Swift. You'll notice that the "with" Objective-C class methods like [NSString stringWithString:@"some other string"] made the transition as "with"-less convenience initializers: NSString(string: "some other string").

Furthermore, you'll need to delegate to a designated initializer from within a convenience initializer.

Also, since you're 1) defining the original class and 2) don't need the convenience initializer scoped differently than the designated initializer, I don't see any reason to place it in an extension.

Putting those together:

class Letter {
    init() { … }

    convenience init(filePath: String) {
        self.init()
        loadFromFile(filePath)
    }

    func loadFromFile(filePath: String) { … }
}

let letter1 = Letter()
letter1.loadFromFile("path1")

let letter2 = Letter(filePath: "path2")

In summary, the analogy for assigning to self in Swift is calling an initializer.

Let me know if this works for you!




回答2:


  1. Convenience initializer must delegate up to designated initializer

It says that convenience init(file_path:String) should call other initialiser

convenience init(file_path:String) {
  self.init()
  //here can set other properties
}
  1. Convenience initialiser usually provide some default parameters

Convenience initialiser are designed to make creation of class instance less complicated. It means that you don't need to pass all arguments to constructor. In your example the class should look like this

  • Designated initializer takess all possible arguments.
  • Convenience provide default value

Code example

// Create instance of a Letter
Letter()
Letter(file_path: "path.txt")
Letter(file_path: "path.txt", option: 0, other: 0)

//Class Implementation 

class Letter
{
  init(file_path: String , option: Int, other: Int) {
    // Instansiate class
  }
}


extension Letter {

  convenience init() {
    self.init(file_path:"a")
  }

  convenience init(file_path:String) {
    self.init(file_path: file_path , option: 0, other: 0)
  }

  class func loadFromFile(file_path:String) -> Letter {
    return Letter()
  }
}

Now you can create instance of Letter this way -




回答3:


You can't assign to self. What about something like this:

class Letter {
}

extension Letter {
    convenience init(filePath: String) {
        self.init()
        // code to load a Letter from a file goes here.
    }

    class func loadFromFile(filePath: String) -> Letter {
        return Letter(filePath: filePath)
    }
}


来源:https://stackoverflow.com/questions/26440263/swift-cannot-assign-to-self-in-a-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!