On 1 April 2017 at 12:03, Adrian Zubarev via swift-evolution < >>> swift-evolution@swift.org> wrote:
First, you should fix the indent in the code samples. Second, remove
any access modifier from inside a protocol. Third, we don’t support default
implementations directly inside protocols yet, so that’s a not valid
example.
Now my personal concerns. As far as I can tell XIB files in an iOS
Project are meant for UIViewControllers in first place, but it’s a common
case that they are also used to create reusable UIViews. The downside of
that abusage is view hierarchy clustering. Most developer creating a view
of Self in Self, which smells to me like really bad code.
MyCustomView // This view is useless
+ MyCustomView
+ CustomSubview1
+ CustomSubview1 // This is probably a dead IBOutlet
In fact Xcode does not use the initializer from NSCoding to show a
live rendered view inside interface builder, instead it will call a UIViews
designated initializer init(frame:). That results that a lot of the
developer write similar code like in the following snippet:
// This pattern results in a similar view cluster like mentioned above
class MyCustomView : UIView {
override init(frame: CGRect) {
let view = loadSomehowFromNib()
self.addSubview(view)
}
}
To solve this problem we’d need some functionality of factory
initializers. I believe as proposed the factory initializer won’t solve
that problem, because everything would be still restricted to a special
initializer annotated with factory.
Personally I would want to write something like this instead.
class MyCustomView : UIView {
override init(frame: CGRect) {
// Instantiating from a Nib file will call `init(coder:)` on MyCustomView
self = loadSomehowFromNib() // assuming () -> MyCustomView
//
self.frame = frame
}
}
This should resolve the clustering issue by assigning the returned
instance from the function to self and create a correct view hierarchy.
+ MyCustomView
+ CustomSubview1
--
Adrian Zubarev
Sent with Airmail
Am 17. März 2017 um 17:26:29, Riley Testut via swift-evolution (
swift-evolution@swift.org) schrieb:
Hi again everyone!
Now that Swift 4 Stage 2 proposals are being considered, I thought it
might be time to revisit this proposal and see if it might align with the
goals set forth for Swift 4.
As a quick tl;dr, this proposal describes a new "factory initializer"
that would allow you to return a value from an initializer. This would have
several benefits, as mentioned in the proposal itself as well as throughout
this mailing list. For convenience, here's a link to the proposal on
GitHub:
https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md
Would love to hear any more comments on this proposal, and if we feel
this is appropriate for considering for Swift 4 I'll happily re-open the
pull request!
Riley Testut
On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> >>>> wrote:
i would appreciate this feature.
For unexperienced developers, its often hard to recognize *when*
factory is a good fit to do the job, and how exactly approach the
implementation. I imagine having this feature built into the language may
help to choose and implement factory when its the right thing to do.
On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution < >>>> swift-evolution@swift.org> wrote:
Is there any chance of reviving this? It seems to me that since this
would require Swift initializers to be implemented internally in such a way
that they can return a value (as Objective-C init methods do), it may
affect ABI stability and thus may be germane to the current stage of Swift
4 development.
Charles
On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution < >>>> swift-evolution@swift.org> wrote:
Recently, I proposed the idea of adding the ability to implement the
"class cluster" pattern from Cocoa (Touch) in Swift. However, as we
discussed it and came up with different approaches, it evolved into a
functionality that I believe is far more beneficial to Swift, and
subsequently should be the focus of its own proposal. So here is the
improved (pre-)proposal:
# Factory Initializers
The "factory" pattern is common in many languages, including
Objective-C. Essentially, instead of initializing a type directly, a method
is called that returns an instance of the appropriate type determined by
the input parameters. Functionally this works well, but ultimately it
forces the client of the API to remember to call the factory method
instead, rather than the type's initializer. This might seem like a minor
gripe, but given that we want Swift to be as approachable as possible to
new developers, I think we can do better in this regard.
Rather than have a separate factory method, I propose we build the
factory pattern right into Swift, by way of specialized “factory
initializers”. The exact syntax was proposed by Philippe Hausler from the
previous thread, and I think it is an excellent solution:
class AbstractBase {
public factory init(type: InformationToSwitchOn) {
return ConcreteImplementation(type)
}
}
class ConcreteImplementation : AbstractBase {
}
Why exactly would this be useful in practice? In my own development,
I’ve come across a few places where this would especially be relevant:
## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think
it would be a very valid use case. The public superclass would declare all
the public methods, and could delegate off the specific implementations to
the private subclasses. Alternatively, this method could be used as an easy
way to handle backwards-compatibility: rather than litter the code with
branches depending on the OS version, simply return the OS-appropriate
subclass from the factory initializer. Very useful.
## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with
protocol extensions to return the appropriate instance conforming to a
protocol for the given needs. Similar to the class cluster/abstract class
method, but can work with structs too. This would be closer to the factory
method pattern, since you don’t need to know exactly what type is returned,
just the protocol it conforms to.
## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory
initializers could definitely help here. Currently, view controllers
associated with a storyboard must be initialized from the client through a
factory method on the storyboard instance (storyboard.
instantiateViewControllerWithIdentifier()). This works when the entire flow
of the app is storyboard based, but when a single storyboard is used to
configure a one-off view controller, having to initialize through the
storyboard is essentially use of private implementation details; it
shouldn’t matter whether the VC was designed in code or storyboards,
ultimately a single initializer should “do the right thing” (just as it
does when using XIBs directly). A factory initializer for a View Controller
subclass could handle the loading of the storyboard and returning the
appropriate view controller.
Here are some comments from the previous thread that I believe are
still relevant:
On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> >>>> wrote:
I can definitely attest that in implementing Foundation we could have
much more idiomatic swift and much more similar behavior to the way
Foundation on Darwin actually works if we had factory initializers.
On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> >>>> wrote:
A `protocol init` in a protocol extension creates an initializer which
is *not* applied to types conforming to the protocol. Instead, it is
actually an initializer on the protocol itself. `self` is the protocol
metatype, not an instance of anything. The provided implementation should
`return` an instance conforming to (and implicitly casted to) the protocol.
Just like any other initializer, a `protocol init` can be failable or
throwing.
Unlike other initializers, Swift usually won’t be able to tell at
compile time which concrete type will be returned by a protocol init(),
reducing opportunities to statically bind methods and perform other
optimization tricks. Frankly, though, that’s just the cost of doing
business. If you want to select a type dynamically, you’re going to lose
the ability to aggressively optimize calls to the resulting instance.
I’d love to hear everyone’s thoughts on this!
Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution