Our company is still sticking to Objective-C, but my goal is to have at least one of our apps use Swift when Swift 2.0 is ready. Today I wrote a small tool in Swift and I'd like to ask a few questions based on that experience. - When implementing delegates in Swift, there were two things that puzzled me: 1) Swift doesn't allow optional methods in a protocol (unless you decorate it, but my goal is Swift-only). 2) I don't have to make my "var delegate" weak? - Swift could implement a few more overloads to make it a bit easier / friendlier to use. I know that you can create what your heart desires by creating extensions, but it takes time, is prone to bugs and distracts from the actual work. For example, the Array type seems to lack a remove method that takes an object argument and a method to find the index of an element. If you use a Set you do get that remove method. The Set's removeAll method forces you to specify a keepCapacity argument, which seems irrelevant in 99% of the use cases? - Why do we call extra initializers in classes "convenience initializers", but just regular extra initializers in structs? - Why do many for-loop examples in Swift write ; ++i at the end instead of i++. It gives a false sense that your loop will start with 1 instead of 0, but I assume it doesn't matter which of the two you write there. - Working with JSON is a pain in Swift. Although Swift 2.0 will make that a bit easier with the guard statement. It doesn't help that Xcode 6.4 doesn't really understand how to indent multiple "if let ..." statements separated by commas. - There is no autocompletion in Xcode of module names when you type "import ..."? - Just a sidenote: the Cocoa classes for OS X need some love. Adding labels, that are actually NSTextFields and setting the text via the oddly named property "stringValue". Even worse is the NSTextView, that you have to dig out of the NSScrollView, dig into its optional textStorage and append a NSAttributedString. A bit of legacy framework that could use some TLC? Thank you.
A Day With Swift
I agree that default implemenations aren't a perfect replacement for all cases of using optional protocol methods, nor am I arguing one way or another for optional methods. I am just offering it as something you might do in a pure Swift project as was asked.
There must be a reason that the Swift team felt the need to restrict optional methods to Objective-C compatible protocols only. I can only guess that the reason is they prefer protocol implementations to have strict compliance and default method implementations seem to fill that void for many cases. Maybe someone from the Swift team can clarify their reasoning and path forward.
Other things you can do is split your protocol into more than one protocol and have multiple optional delegates. That may be preferable for some cases where you may only have two optional delegates for example.
There is is an operator to compare for equality of reference (===), but Equatable doesn't automatically use it. My guess is that doing so would make "equality" ambiguous, leading to confusion and errors.
Keep in mind that the Obj-C Equatable equivalent ('isEqual:') has exactly these problems. It's pointer equality by default (in the NSObject implementation), and you have to memorize the actual behavior in a number of special cases (NSArray and other collection classes), and in other cases you have to realy on the documentation being correct or you have to guess.
Swift's approach is less convenient sometimes, but more reliable.
It's a really odd thing for the guide to say.
If you're using an "++" operator within a larger expression, then there's no choice in the matter — pre-increment and post-increment mean different things, and it's a bug to use the wrong one.
If you're using the operator standalone — in a complete statement that just increments a variable — then it truly doesn't matter which you use. I have no idea why one form would be "typical expected behavior" because it's not typical of anything, it's subject to different expectations from different people, and it has no behavior of "returning the result" because the result isn't being used.
A better piece of advice would be, "Don't use ++ within larger expressions ever."
Preferring the pre-increment operator to the post-increment operator in all situations except those where post-increment is actually necessary is a pretty standard guideline you'll find nearly everywhere. Both for reasons of clarity and for efficiency (as the post-increment requires generating a separate return value).
At the moment Swift is built on the Objective-C runtime and requires its use for any dynamic messaging like optional protocol methods. IIRC the Swift devs discussed this in the old dev forums a few times but I cannot remember the specifics. I think they said Swift may get its own dynamic runtime sometime down the road.
At some point during the beta process last year, they added the 'dynamic' keyword to make the dynamic dispatch disctinction more runtime agnostic (previously you used the @objc keyword for that). It is interesting they didn't do the same for optional protocols. I doubt it's because they don't intend Swift to "natively" support such things. More likely it's because the use of the Objective-C runtime means optional protocols can't be applied to structs or enums and they want to make it clear this is an @objc based behavior for now. It will probably change some day in the future. But I'm only guessing.
Equatable has to be able to apply to value types as well as reference types, and === can only work with reference types (it doesn't even make sense with value types).
I suppose they could somehow make Equatable into a generic protocol Equatable<T, U>, then have a protocol extension on Equatable that provides a default implementation using "===" but only for T & U of AnyObject…but that starts to get complicated. And special-casey, since anything that uses Equatable as a constraint now how to also verify that T & U are either AnyObject or a value type that conforms to Equatable given T & U. I don't even know how that would work if you have T that is a value type and U that is a reference type.