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 
([email protected]) 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 <[email protected]> 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 
<[email protected]> 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 
<[email protected]> 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 <[email protected]> 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 <[email protected]> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to