问题
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:
- 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
}
- 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