What's new in Swift 3.0
Swift3.0 is changingpretty much everything,and your code will almost certainly refuse to build until you make the necessary changes. SerIoUsly,if you thought the jump from Swift 1.2 to 2.0 was big,you ain't seen nothing yet.
In this article I'm going to explain some of the most important changes with as many code examples as I can,and hopefully this will give you some chance to be prepared to update your code when Swift 3.0 goes final. There are many more changes than the ones listed below,but the changes below are the ones that are most likely to hit you.
If you liked this article,you might also enjoy these:
- What's new in iOS 10?
- What's new in Swift 2.2?
- What's new in Swift 2.0?
- My free Swift tutorial series
- Buy my Pro Swift book
- Buy Objective-C for Swift Developers
ADVANCE WARNING #1:Swift 3.0 is still under development. This article will be updated as new changes are announced.
ADVANCE WARNING #2:There are lots and lots of changes,some of which might seem petty. However,the hope is that these changes are a once-off event that makes the language better for years to come,and it ought to mean that changes in later versions are significantly smaller.
ADVANCE WARNING #3:If you have not already read mywhat's new in Swift 2.2article,you should do so now –everything that I said was deprecated there has been removed,including ++,--,C-style for loops,tuple splat Syntax,and more.
All function parameters have labels unless you request otherwise
The way we call functions and methods already changed in Swift 2.0,but it's changing again and this time it's going to breakeverything. In Swift 2.x and earlier,method names did not require a label for their first parameter,so the name of the first parameter was usually built into the method name. For example:
<code class=" language-swift" style="font-family: Consolas,monospace; padding: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; background-image: none; background-position: initial initial; background-repeat: initial initial;">names<span class="token punctuation" style="color:#999999;">.</span><span class="token function" style="color:#dd4a68;">indexOf</span><span class="token punctuation" style="color:#999999;">(</span><span class="token string" style="color:#66990;">"Taylor"</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token string" style="color:#66990;">"Taylor"</span><span class="token punctuation" style="color:#999999;">.</span><span class="token function" style="color:#dd4a68;">writeToFile</span><span class="token punctuation" style="color:#999999;">(</span><span class="token string" style="color:#66990;">"filename"</span><span class="token punctuation" style="color:#999999;">,</span> atomically<span class="token punctuation" style="color:#999999;">:</span> <span class="token boolean" style="color:#99055;">true</span><span class="token punctuation" style="color:#999999;">,</span> encoding<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">NSUTF8StringEncoding</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token builtin" style="color:#66990;">SKAction</span><span class="token punctuation" style="color:#999999;">.</span><span class="token function" style="color:#dd4a68;">rotateByAngle</span><span class="token punctuation" style="color:#999999;">(</span><span class="token function" style="color:#dd4a68;">CGFloat</span><span class="token punctuation" style="color:#999999;">(</span><span class="token builtin" style="color:#66990;">M_PI_2</span><span class="token punctuation" style="color:#999999;">)</span><span class="token punctuation" style="color:#999999;">,</span> duration<span class="token punctuation" style="color:#999999;">:</span> <span class="token number" style="color:#99055;">10</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token builtin" style="color:#66990;">UIFont</span><span class="token punctuation" style="color:#999999;">.</span><span class="token function" style="color:#dd4a68;">preferredFontForTextStyle</span><span class="token punctuation" style="color:#999999;">(</span><span class="token builtin" style="color:#66990;">UIFontTextStyleSubheadline</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token keyword" style="color:#077aa;">override</span> <span class="token keyword" style="color:#077aa;">func</span> <span class="token function" style="color:#dd4a68;">numberOfSectionsInTableView</span><span class="token punctuation" style="color:#999999;">(</span>tableView<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UITableView</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token operator" style="color:#a67f59;">-</span><span class="token operator" style="color:#a67f59;">></span> <span class="token builtin" style="color:#66990;">Int</span> <span class="token keyword" style="color:#077aa;">func</span> <span class="token function" style="color:#dd4a68;">viewForZoomingInScrollView</span><span class="token punctuation" style="color:#999999;">(</span>scrollView<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UIScrollView</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token operator" style="color:#a67f59;">-</span><span class="token operator" style="color:#a67f59;">></span> <span class="token builtin" style="color:#66990;">UIView</span><span class="token operator" style="color:#a67f59;">?</span> <span class="token builtin" style="color:#66990;">NSTimer</span><span class="token punctuation" style="color:#999999;">.</span><span class="token function" style="color:#dd4a68;">scheduledTimerWithTimeInterval</span><span class="token punctuation" style="color:#999999;">(</span><span class="token number" style="color:#99055;">0.35</span><span class="token punctuation" style="color:#999999;">,</span> target<span class="token punctuation" style="color:#999999;">:</span> <span class="token keyword" style="color:#077aa;">self</span><span class="token punctuation" style="color:#999999;">,</span> selector<span class="token punctuation" style="color:#999999;">:</span> #<span class="token function" style="color:#dd4a68;">selector</span><span class="token punctuation" style="color:#999999;">(</span>createEnemy<span class="token punctuation" style="color:#999999;">)</span><span class="token punctuation" style="color:#999999;">,</span> userInfo<span class="token punctuation" style="color:#999999;">:</span> <span class="token constant" style="color:#99055;">nil</span><span class="token punctuation" style="color:#999999;">,</span> repeats<span class="token punctuation" style="color:#999999;">:</span> <span class="token boolean" style="color:#99055;">true</span><span class="token punctuation" style="color:#999999;">)</span></code>
Swift 3 makes all labels required unless you specify otherwise,which means the method names no longer detail their parameters. In practice,this often means the last part of the method name gets moved to be the name of the first parameter.
To show you how that looks,here is that Swift 2.2 code followed by its equivalent in Swift 3:
Those are methods youcall,but this has a knock-on effect for many methods thatget calledtoo: when you're connecting to frameworks such as UIKit,they expect to follow the old-style "no first parameter name" rule even in Swift 3.
Here are some example signatures from Swift 2.2:
IoUsTraitCollection<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UITraitCollection</span><span class="token operator" style="color:#a67f59;">?</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token keyword" style="color:#077aa;">func</span> <span class="token function" style="color:#dd4a68;">textFieldShouldReturn</span><span class="token punctuation" style="color:#999999;">(</span>textField<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UITextField</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token operator" style="color:#a67f59;">-</span><span class="token operator" style="color:#a67f59;">></span> <span class="token builtin" style="color:#66990;">Bool</span></code>In Swift 3,they all need an underscore before the first parameter,to signal that the caller (Objective-C code) won't be using a parameter label:
IoUsTraitCollection<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UITraitCollection</span><span class="token operator" style="color:#a67f59;">?</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token keyword" style="color:#077aa;">func</span> <span class="token function" style="color:#dd4a68;">textFieldShouldReturn</span><span class="token punctuation" style="color:#999999;">(</span><span class="token number" style="color:#99055;">_</span> textField<span class="token punctuation" style="color:#999999;">:</span> <span class="token builtin" style="color:#66990;">UITextField</span><span class="token punctuation" style="color:#999999;">)</span> <span class="token operator" style="color:#a67f59;">-</span><span class="token operator" style="color:#a67f59;">></span> <span class="token builtin" style="color:#66990;">Bool</span></code>Omit needless words
When Swift went open source in December 2015,its shiny new API guideliness contained three fateful words: "omit needless words." This introduces another huge raft of breaking changes in Swift 3,because it means that method names that contain self-evident words now have those words removed.
Let's look at some simple examples first. First,Swift 2.2:
Can you identify the needless words? When you're working with
UIColor
,of course blue is going to be a color,so sayingblueColor()
is needless. When you append one attributed string to another,do you really need to specify that it's an attributed string you're appending as opposed to an elephant?Here is that same code in Swift 3:
As you can see,this makes method names significantly shorter!
This change has particularly affected strings,which had repetition all over the place. The best way to demonstrate this is to show before and after code side-by-side,so in the code below the first line of each pair is Swift 2.2 and the second is Swift 3.0:
Warning:
capitalized
is still a property,butlowercaseString
anduppercaseString
have been transmogrified into the methodslowercased()
anduppercased()
.I've chosen the examples so far because the jump to Swift 3 isn't vast,but there are quite a few changes that were significant enough to make my brain hit a speedbump– usually when the resulting method is so short that it wasn't immediately obvIoUs what it was.
For example,look at this code:
When I first saw that,I blanked: "dismiss what?" That's partly a result of theStockholm syndromethat's inevitable having programmed foriOSfor so long,but once you learn to reverse the parameter label change and re-add the needless words,you can see it's equivalent to this code in Swift 2.2:
A similar change happened to
prepareForSegue()
,which now looks like this:Intermission
If you're enjoying this article,you might like my Swift newsletter. I post very rarely,but always include discounts on my books –click here to sign up nowand you'll get aninstant $5 discounton the complete Hacking with Swift e-bookincludinga free update for Swift 3.0.
And now back to your regularly scheduled broadcast…
UpperCamelCase has been replaced with lowerCamelCase for enums and properties
Although syntactically irrelevant,the capital letters we use to name classes and structs,properties,enums,and more have always followed a convention fairly closely: classes,structs,and enums use UpperCamelCase (MyStruct,WeatherType.Cloudy),properties and parameter names use lowerCamelCase (emailAddress,requestString).
I say "fairly closely" because there are some exceptions that are going tostopbeing exceptions in Swift 3: properties and parameters that started with initials in Swift 2.2 will now used lowerCamelCase in Swift 3.
Sometimes this isn't too strange: Swift 2.2 created
NSURLRequest
objects usingNSURLRequest(URL: someURL)
–note the capital "URL". Swift 3 rewrites that toNSURLRequest(url: someURL)
,and also means you'll use things likewebView.request?.url?.absoluteString
for reading the URL of a web view.Where it's a bit more jarring is when only part of the property name is in caps,e.g.
CGColor
orCIColor
. Yes,you've guessed it: they becomecgColor
andciColor
in Swift 3,so you'll be writing code like this:This change does help drive consistency: all properties and parameters should start with a lowercase letter,no exceptions.
At the same time enum cases are also changing,moving from UpperCamelCase to lowerCamelCase. This makes sense: an enum is a data type (like a struct),but enum values are closer to properties. However,it does mean that wherever you've used an Apple enum,it will now be lowercase. So:
You get the idea. However,this tiny change brings something much bigger because Swift's optionals are actually just an enum under the hood,like this:
This means if you use
.Some
to work with optionals,you'll need to switch to.some
instead. Of course,you could always take this opportunity to ditch.some
entirely – these two pieces of code are identical:Swifty importing of C functions
Swift 3 introduces attributes for C functions that allow library authors to specify new and beautiful ways their code should be imported into Swift. For example,all those functions that start with "CGContext" now get mapped to properties methods on a CGContext object,which makes for much more idiomatic Swift. Yes,this means the hideous wart that is
CGContextSetFillColorWithColor()
has finally been excised.To demonstrate this,here's an example in Swift 2.2:
In Swift 3 the
CGContext
can be treated as an object that you can call methods on rather than repeatingCGContext
again and again. So,we can rewrite that code like this:Note: in both Swift 2.2 and Swift 3.0
UIGraphicsGetCurrentContext()
returns an optionalCGContext
,but because Swift 3 uses method calls we need to safely unwrap before it's used.This mapping of C functions exists elsewhere,for example you can now read the
numberOfPages
property of aCGPDFDocument
,andCGAffineTransform
has been souped up quite dramatically. Here are some examples showing old and new:Verbs and nouns
This is the part where some people will start to drift off in confusion,which is a shame because it's important.
Here's are some quotes from the Swift API guidelines:
- "When the operation is naturally described by a verb,use the verb’s imperative for the mutating method and apply the “ed” or “ing” suffix to name its nonmutating counterpart"
- "Prefer to name the nonmutating variant using the verb’s past participle"
- "When adding “ed” is not grammatical because the verb has a direct object,name the nonmutating variant using the verb’s present participle"
- "When the operation is naturally described by a noun,use the noun for the nonmutating method and apply the “form” prefix to name its mutating counterpart"
Got that? It's no surprise that Swift's rules are expressed using lingustic terminology –it is after all a language! – but this at least gives me a chance to feel smug that I did a second degree in English. What it means is that many methods are changing names in subtle and sometimes confusing ways.
Let's start with a couple of simple examples:
Each time Swift 3 modifies the method by adding a "d" to the end: this is a value that's being returned.
These rules are mostly innocent enough,but it causes confusion when it comes to array sorting. Swift 2.2 used
sort()
to return a sorted array,244)">sortInPlace()to sort an array in place. In Swift 3.0,sort()
is renamed tosorted()
(following the examples above),244)">sortInPlace()is renamed tosort()
.TL;DR: This means you need to be careful because in Swift 2.2
sort()
returned a sorted array,but in Swift 3.0sort()
sorts the array in place.Why all this change?
It's easy to read these changes,some of which are tiny but introduce massive breakage,and imagine that Apple's Swift engineers are just out to make our lives harder. However,the truth is that they are working hard to make sure Swift is as easy to learn,easy to use,and fast as possible,which are three very different priorities.
In particular,I have been struck by how committed the Apple team are to ensuring their changes are discussed and agreed in the open,as part of the Swift Evolution community effort. Every change above went through extensive community discussion before being agreed for Swift 3.0,which is an incredible thing to behold.
You can get involved and help shape these changesgoing forward: they are keen to hear ideas from a wide range of users,and it means the future of Swift really is in your hands.
原文链接:https://www.f2er.com/swift/322773.html