i've my own valueof system,which determines the wa

Swift Blog - Apple Developer
Xcode 6.1 introduces yet another way to experiment with Swift in the form of an interactive Read Eval Print Loop, or REPL. Developers familiar with interpreted languages will feel comfortable in this command-line environment, and even experienced developers will find a few unique features. To get started, launch Terminal.app (found in /Applications/Utilities) and type “swift” at the prompt in OS X Yosemite, or “xcrun swift” in OS X Mavericks. You’ll then be in the Swift REPL:Welcome to Swift version 1.1 (swift-600.0.20.0). Type :help for assistance.
All you need to do is type Swift statements and the REPL will immediately execute your code.
Expression results are automatically formatted and displayed along with their type, as are the results of both variable and constant declarations.
Console output flows naturally within the interactive session:
1& "100".toInt()
$R0: Int? = 100
2& let name = "Katherine"
name: String = "Katherine"
3& println("Hello, \(name)")
Hello, KatherineNote that the result from line one has been given a name by the REPL even though the result of the expression wasn’t explicitly assigned to anything.
You can reference these results to reuse their values in subsequent statements:
4& $R0! + 200
$R1: Int = 300The Swift compiler recognizes incomplete code, and will prompt for additional input when needed.
Your code will even be indented automatically as it would in Xcode. For instance, starting a function:5& func timesTwo() {
The prompt for continuation lines is a line number followed by a period instead of the angle bracket that indicates a new statement, so you can tell at a glance when you’re being asked to complete a code fragment.
At this point you can keep typing remaining lines in the method:5& func timesTwo() {
return value * 2
There are three noteworthy points to make here:
The first is that line six was originally indented, but the REPL automatically unindented when we typed the closing brace.
The second is that the function references a parameter we forgot to declare and needs a return type, so you’ll need to add both to the declaration.
The last is that even if you did press return after the last line, it’s not too late to fix it.Multi-Line HistoryWhen code is submitted to the compiler it’s also recorded in the REPL history, which makes correcting mistakes trivial.
If you pressed return at the end of the incomplete function declaration above, you’d be presented with the following message:error: use of unresolved identifier 'value'Like most history implementations, you can call up your last entry by pressing up arrow from the prompt.
The REPL brings back all three lines in our example, and places the cursor at the end.
You can now proceed with editing the code to correct your mistake as described in the next section.Your history is preserved between sessions and will record hundreds of code fragments.
Each time you move up from the top line you’ll move to an earlier history entry.
Each time you move down from an empty line at the bottom of an entry you’ll move to a more recent history entry.
The empty line that opens up before moving to the next entry comes in handy for reasons discussed below.Multi-Line EditingEven though the REPL behaves like a traditional line editor, it also provides convenient features for dealing with multi-line input like most class or function declarations.
In the example above, before pressing return on the final line you can press up arrow to move the cursor up to the declaration line, then use the left arrow to move the cursor just after the opening parenthesis for the parameter list:5& func timesTwo() {
return value * 2
7. }Type the parameter declaration, press the right arrow to move past the closing parenthesis and add the return type as well:5& func timesTwo(value: Int) -& Int {
return value * 2
7. }You can’t press return to complete the declaration at this point because you’re in the middle of a block of text.
Pressing return here would insert a line break, which can be useful if you’re trying to insert additional lines in a function or method body, but what you want here is to move to the end of the declaration.
You can press down arrow twice to get there, or use the Emacs sequence ESC > (the escape key followed by a closing angle bracket).
Pressing return at the end of the last line will compile the newly declared function so it’s ready for use:
timesTwo(21)
$R2: (Int) = 42Automatic detection of statement completion means that you can just type code and the REPL will do the right thing the vast majority of the time.
There are occasions, however, where it’s necessary to submit more than one declaration at the same time because they have mutual dependencies. Consider the following code:func foo() {
func bar() {
}Typing everything above line by line will result in trying to compile the first function once the third line is complete, and of course this produces an error:error: use of unresolved identifier 'bar'You could declare both functions on a single line to get around automatic completion detection that takes place when you press return, but there’s a better solution.
After typing the third line above you can press the down arrow to move to create a fourth line manually, and type the remainder normally.
The two declarations are compiled together, achieving the desired goal of mutual recursion.Quick ReferenceTo help you get started, here’s a handy chart with some of the most commonly used editing and navigation keys:Arrow Keys
Move cursor left/right/up/down
Move cursor right one character, same as right arrow
Move cursor left one character, same as left arrow
Move cursor to end of next line, same as down arrow
Move cursor to end of prior line, same as up arrow
Delete the character under the cursor
Option+Left
Move cursor to start of prior word
Option+Right Move cursor to start of next word
Move cursor to start of current line
Move cursor to end of current line
Delete the character to the left of the cursor
Move cursor to start of first line
Move cursor to end of last line
Swift version 1.1 is new in , and it introduces a new feature: failable initializers. Initialization is the process of providing initial values to each of the stored properties of a class or struct, establishing the invariants of the object. In some cases initialization can fail. For example, initializing the object requires access to a resource, such as loading an image from a file:NSImage(contentsOfFile: "swift.png")If the file does not exist or is unreadable for any reason, the initialization of the NSImage will fail. With Swift version 1.1, such failures can be reported using a failable initializer. When constructing an object using a failable initializer, the result is an optional that either contains the object (when the initialization succeeded) or contains nil (when the initialization failed). Therefore, the initialization above should handle the optional result directly:if let image = NSImage(contentsOfFile: "swift.png") {
}An initializer defined with init can be made failable by adding a ? or a ! after the init, which indicates the form of optional that will be produced by constructing an object with that initializer. For example, one could add a failable initializer to Int that attempts to perform a conversion from a String:extension Int {
init?(fromString: String) {
if let i = fromString.toInt() {
return nil
}In a failable initializer, return nil indicates that initi no other value can be returned. In the example, failure occurs when the string could not be parsed as an integer. Otherwise, self is initialized to the parsed value.Failable initializers eliminate the most common reason for factory methods in Swift, which were previously the only way to report failure when constructing this object. For example, enums that have a raw type provided a factory method fromRaw that returned an optional enum. Now, the Swift compiler synthesizes a failable initializer that takes a raw value and attempts to map it to one of the enum cases. For example:enum Color : Int {
case Red = 0, Green = 1, Blue = 2
var rawValue: Int {
init?(rawValue: Int) {
switch rawValue {
case 0: self = .Red
case 1: self = .Green
case 2: self = .Blue
default: return nil
}Using the failable initializer allows greater use of Swift’s uniform construction syntax, which simplifies the language by eliminating the confusion and duplication between initializers and factory methods. Along with the introduction of failable initializers, Swift now treats more Cocoa factory methods — those with NSError arguments — as initializers, providing a more uniform experience for object construction. You can read more about failable initializers in .
So far the Swift blog has focused on advanced programming topics, including the design principles of the Swift language. We thought it would be helpful to provide content for programmers who are new to Swift and just trying Xcode for the first time. To make it more approachable for everyone, we put together a very short video that demonstrates how to build an iOS app in Swift from scratch, in less than ten minutes.
Two occasionally useful features of C are the __FILE__ and __LINE__ magic macros. These are built into the preprocessor, and expanded out before the C parser is run. Despite not having a preprocessor, Swift provides very similar functionality with similar names, but Swift works quite differently under the covers.Built-In IdentifiersAs described in , Swift has a number of built-in identifiers, including
__FILE__, __LINE__, __COLUMN__, and __FUNCTION__. These expressions can be used anywhere and are expanded by the parser to string or integer literals that correspond to the current location in the source code. This is incredibly useful for manual logging, e.g. to print out the current position before quitting.However, this doesn’t help us in our quest to implement assert().
If we defined assert like this:func assert(predicate : @autoclosure () -& Bool) {
if !predicate() {
println("assertion failed at \(__FILE__):\(__LINE__)")
}The above code would print out of the file/line location that implements assert() itself, not the location from the caller. That isn’t helpful.Getting the location of a callerSwift borrows a clever feature from the D language: these identifiers expand to the location of the caller when evaluated in a default argument list.
To enable this behavior, the assert() function is defined something like this:func assert(condition: @autoclosure () -& Bool, _ message: String = "",
file: String = __FILE__, line: Int = __LINE__) {
if !condition() {
println("assertion failed at \(file):\(line): \(message)")
}The second parameter to the Swift assert() function is an optional string that you can specify, and the third and forth arguments are defaulted to be the position in the caller’s context.
This allows assert() to pick up the source location of the caller by default, and if you want to define your own abstractions on top of assert, you can pass down locations from its caller.
As a trivial example, you could define a function that logs and asserts like this:func logAndAssert(condition: @autoclosure () -& Bool, _ message: StaticString = "",
file: StaticString = __FILE__, line: UWord = __LINE__) {
logMessage(message)
assert(condition, message, file: file, line: line)
}This properly propagates the file/line location of the logAndAssert() caller down to the implementation of assert(). Note that StaticString, as shown in the code above, is a simple String-like type used to store a string literal, such as one produced by __FILE__, with no memory-management overhead.In addition to being useful for assert(), this functionality is used in the Swift implementation of the higher-level XCTest framework, and may be useful for your own libraries as well.
On June 2, 2014 at WWDC, the Swift team finally showed you what we had been working on for years. That was a
big day with lots of excitement, for us and for developers around the world. Today, we’ve reached the second giant milestone:Swift version 1.0 is now GM.You can now submit your apps that use Swift to the App Store. Whether your app uses Swift for a small feature or a complete application, now is the time to share your app with the world. It’s your turn to excite everyone with your new creations.Swift for OS XToday is the GM date for Swift on iOS. We have one more GM date to go for Mac. Swift for OS X currently requires the SDK for OS X Yosemite, and when Yosemite ships later this fall, Swift will also be GM on the Mac. In the meantime, you can keep developing your Mac apps with Swift by downloading the beta of .The Road AheadYou’ll notice we’re using the word “GM”, not “final”. That’s because Swift will continue to advance with new features, improved performance, and refined syntax. In fact, you can expect a few improvements to come in Xcode 6.1 in time for the Yosemite launch. Because your apps today embed a version of the Swift GM runtime, they will continue to run well into the future.
In Swift, a pattern is a way to describe and match a set of values based on certain rules, such as: All tuples whose first value is 0All numbers in the range 1...5All class instances of a certain typeThe learning playground linked below includes embedded documentation and experiments for you to perform. Download it for an interactive experience that will give you a jump start into using patterns in your own apps.This playground requires the latest beta version of Xcode 6 on OS X Mavericks or OS X Yosemite beta.
This post explores how optionals help preserve strong type safety within Swift. We’re going to create a Swift version of an Objective-C API. Swift doesn’t really need this API, but it makes for a fun example.In Objective-C, NSDictionary has a method -objectsForKeys:notFoundMarker: that takes an NSArray of keys, and returns an NSArray of corresponding values. From the documentation: “the N-th object in the returned array corresponds to the N-th key in [the input parameter] keys.” What if the third key isn’t actually in the dictionary? That’s where the notFoundMarker parameter comes in. The third element in the array will be this marker object rather than a value from the dictionary. The Foundation framework even provides a class for this case if you don’t have another to use: NSNull.In Swift, the Dictionary type doesn’t have an objectsForKeys equivalent. For this exercise, we’re going to add one — as valuesForKeys in keeping with the common use of ‘value’ in Swift — using an extension:extension Dictionary {
func valuesForKeys(keys: [K], notFoundMarker: V) -& [V] {
}This is where our new implementation in Swift will differ from Objective-C. In Swift, the stronger typing restricts the resulting array to contain only a single type of element — we can’t put NSNull in an array of strings. However, Swift gives an even better option: we can return an array of optionals. All our values get wrapped in optionals, and instead of NSNull, we just use nil.extension Dictionary {
func valuesForKeys(keys: [Key]) -& [Value?] {
var result = [Value?]()
result.reserveCapacity(keys.count)
for key in keys {
result.append(self[key])
return result
}NOTE: Some of you may have guessed why a Swift Dictionary doesn’t need this API, and already imagined something like this:extension Dictionary {
func valuesForKeys(keys: [Key]) -& [Value?] {
return keys.map { self[$0] }
}This has the exact same effect as the imperative version above, but all of the boilerplate has been wrapped up in the call to map. This is great example why Swift types often have a small API surface area, because it’s so easy to just call map directly.Now we can try out some examples:let dict = ["A": "Amir", "B": "Bertha", "C": "Ching"]
dict.valuesForKeys(["A", "C"])
dict.valuesForKeys(["B", "D"])
dict.valuesForKeys([])
Nested OptionalsNow, what if we asked for the last element of each result?dict.valuesForKeys(["A", "C"]).last
dict.valuesForKeys(["B", "D"]).last
dict.valuesForKeys([]).last
That’s strange — we have two levels of Optional in the first case, and Optional(nil) in the second case. What’s going on?Remember the declaration of the last property:var last: T? { get }This says that the last property’s type is an Optional version of the array’s element type. In this case, the element type is also optional (String?). So we end up with String??, a doubly-nested optional type.So what does Optional(nil) mean?Recall that in Objective-C we were going to use NSNull as a placeholder. The Objective-C version of these three calls looks like this:[dict valuesForKeys:@[@"A", @"C"] notFoundMarker:[NSNull null]].lastObject
[dict valuesForKeys:@[@"B", @"D"] notFoundMarker:[NSNull null]].lastObject
[dict valuesForKeys:@[] notFoundMarker:[NSNull null]].lastObject
In both the Swift and Objective-C cases, a return value of nil means “the array is empty, therefore there’s no last element.” The return value of Optional(nil) (or in Objective-C NSNull) means “the last element of this array exists, but it represents an absence.” Objective-C has to rely on a placeholder object to do this, but Swift can represent it in the type system.Providing a DefaultTo wrap up, what if you did want to provide a default value for anything that wasn’t in the dictionary? Well, that’s easy enough.extension Dictionary {
func valuesForKeys(keys: [Key], notFoundMarker: Value) -& [Value] {
return self.valuesForKeys(keys).map { $0 ?? notFoundMarker }
dict.valuesForKeys(["B", "D"], notFoundMarker: "Anonymous")
While Objective-C has to rely on a placeholder object to do this, Swift can represent it in the type system, and provides rich syntactic support for handling optional results.
The response to support for access control in Swift has been extremely positive. However, some developers have been asking, “Why doesn’t Swift have something like protected?” Many other programming languages have an access control option that restricts certain methods from being accessed from anywhere except subclasses.When designing access control levels in Swift, we considered two main use cases:keep private details of a class hidden from the rest of the appkeep internal details of a framework hidden from the client appThese correspond to private and internal levels of access, respectively.In contrast, protected conflates access with inheritance, adding an entirely new control axis to reason about. It doesn’t actually offer any real protection, since a subclass can always expose “protected” API through a new public method or property. It doesn’t offer
additional optimization opportunities either, since new overrides can come from anywhere. And it’s unnecessarily restrictive — it allows subclasses, but not any of the subclass’s helpers, to access something.As some developers have pointed out, Apple frameworks do occasionally separate parts of API intended for use by subclasses. Wouldn’t protected be helpful here? Upon inspection, these methods generally fall into one of two groups. First, methods that aren’t really useful outside the subclass, so protection isn’t critical (and recall the helper case above). Second, methods that are designed to be overridden but not called. An example is drawRect(_:), which is certainly used within the UIKit codebase but is not to be called outside UIKit.It’s also not clear how protected should interact with extensions. Does an extension to a class have access to that class’s protected members? Does an extension to a subclass have access to the superclass’s protected members? Does it make a difference if the extension is declared in the same module as the class?There was one other influence that led us to the current design: existing practices of Objective-C developers both inside and outside of Apple. Objective-C methods and properties are generally declared in a public header (.h) file, but can also be added in class extensions within the implementation (.m) file. When parts of a public class are intended for use elsewhere within the framework but not outside, developers create a second header file with the class’s “internal” bits. These three levels of access correspond to public, private, and internal in Swift.Swift provides access control along a single, easy-to-understand axis, unrelated to inheritance. We believe this model is simpler, and provides access control the way it is most often needed: to isolate implementation details to within a class or within a framework. It may be different from what you’ve used before, but we encourage you to try it out.
Types in Swift fall into one of two categories: first, “value types”, where each instance keeps a unique copy of its data, usually defined as a struct, enum, or tuple. The second, “reference types”, where instances share a single copy of the data, and the type is usually defined as a class. In this post we explore the merits of value and reference types, and how to choose between them.
What’s the Difference?
The most basic distinguishing feature of a value type is that copying — the effect of assignment, initialization, and argument passing — creates an independent instance with its own unique copy of its data:
struct S { var data: Int = -1 }
var a = S()
a.data = 42
println("\(a.data), \(b.data)")
Copying a reference, on the other hand, implicitly creates a shared instance. After a copy, two variables then refer to a single instance of the data, so modifying data in the second variable also affects the original, e.g.:
class C { var data: Int = -1 }
var x = C()
x.data = 42
println("\(x.data), \(y.data)")
The Role of Mutation in Safety One of the primary reasons to choose value types over reference types is the ability to more easily reason about your code. If you always get a unique, copied instance, you can trust that no other part of your app is changing the data under the covers. This is especially helpful in multi-threaded environments where a different thread could alter your data out from under you. This can create nasty bugs that are extremely hard to debug. Because the difference is defined in terms of what happens when you change data, there’s one case where value and reference types overlap: when instances have no writable data. In the absence of mutation, values and references act exactly the same way. You may be thinking that it could be valuable, then, to have a case where a class is completely immutable. This would make it easier to use Cocoa NSObject objects, while maintaining the benefits of value semantics. Today, you can write an immutable class in Swift by using only immutable stored properties and avoiding exposing any APIs that can modify state. In fact, many common Cocoa classes, such as NSURL, are designed as immutable classes. However, Swift does not currently provide any language mechanism to enforce class immutability (e.g. on subclasses) the way it enforces immutability for struct and enum. How to Choose? So if you want to build a new type, how do you decide which kind to make? When you’re working with Cocoa, many APIs expect subclasses of NSObject, so you have to use a class. For the other cases, here are some guidelines: Use a value type when:
Comparing instance data with == makes sense You want copies to have independent state The data will be used in code across multiple threads
Use a reference type (e.g. use a class) when:
Comparing instance identity with === makes sense You want to create shared, mutable state
In Swift, Array, String, and Dictionary are all value types. They behave much like a simple int value in C, acting as a unique instance of that data. You don’t need to do anything special — such as making an explicit copy — to prevent other code from modifying that data behind your back. Importantly, you can safely pass copies of values across threads without synchronization. In the spirit of improving safety, this model will help you write more predictable code in Swift.
Many people have asked about the Balloons playground we demonstrated when introducing Swift at WWDC. Balloons shows that writing code can be interactive and fun, while presenting several great features of playgrounds. Now you can learn how the special effects were done with this tutorial version of ‘Balloons.playground’, which includes documentation and suggestions for experimentation.This playground uses new features of SpriteKit and requires the latest beta versions of Xcode 6 and OS X Yosemite.
The boolean Bool type in Swift underlies a lot of primitive functionality, making it an interesting demonstration of how to build a simple type. This post walks through the creation of a new MyBool type designed and implemented to be very similar to the Bool type built into Swift. We hope this walk through the design of a simple Swift type will help you better understand how the language works. Let’s start with the basic definition. The MyBool type models two different cases, perfect for an enum: enum MyBool {
case myTrue, myFalse
} To reduce confusion in this post, we’ve named the cases myTrue and myFalse. We want MyBool() to produce a false value, and can do so by providing an init method: extension MyBool {
init() { self = .myFalse }
} Swift enum declarations implicitly scope their enumerators within their body, allowing us to refer to MyBool.myFalse and even .myFalse when a contextual type is available.
However, we want our type to work with the primitive true and false literal keywords. To make this work, we can make MyBool conform to the BooleanLiteralConvertible protocol like this: extension MyBool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -& MyBool {
return value ? myTrue : myFalse
var a : MyBool = true With this set up, we have our basic type, but we still can’t do much with it.
Booleans need to be testable within an if condition.
Swift models this with the BooleanType protocol, which allows any type to be used as a logical condition: extension MyBool : BooleanType {
var boolValue: Bool {
switch self {
case .myTrue: return true
case .myFalse: return false
if a {} We also want anything that conforms to BooleanType to be castable to MyBool, so we add: extension MyBool {
init(_ v : BooleanType) {
if v.boolValue {
self = .myTrue
self = .myFalse
var basicBool : Bool = true
a = MyBool(basicBool) Note that the use of _ in the initializer argument list disables the keyword argument, which allows the MyBool(x) syntax to be used instead of requiring MyBool(v: x). Now that we have basic functionality, let’s define some operators to work with it, starting with the == operator.
Simple enums that have no associated data (like MyBool) are automatically made Equatable by the compiler, so no additional code is required. However, you can make arbitrary types equatable by conforming to the Equatable protocol and implementing the == operator. If MyBool weren’t already Equatable, this would look like this: extension MyBool : Equatable {
func ==(lhs: MyBool, rhs: MyBool) -& Bool {
switch (lhs, rhs) {
case (.myTrue,.myTrue), (.myFalse,.myFalse):
return true
return false
if a == a {}
if a != a {} Here we’re using some simple pattern matching in the switch statement to handle this. Since MyBool is now Equatable, we get a free implementation of the != operator.
Lets add binary operations: func &(lhs: MyBool, rhs: MyBool) -& MyBool {
return rhs
return false
func |(lhs: MyBool, rhs: MyBool) -& MyBool {
return true
return rhs
func ^(lhs: MyBool, rhs: MyBool) -& MyBool {
return MyBool(lhs != rhs)
} With the basic operators in place, we can implement a variety of helpful unary and compound assignment operators as well, for example: prefix func !(a: MyBool) -& MyBool {
return a ^ true
func &=(inout lhs: MyBool, rhs: MyBool) {
lhs = lhs & rhs
} The &= operator takes the left operand as inout because it reads and writes to it, and the effect must be visible to the user of the operator.
Swift gives you complete control over mutability of operations on value types like enum and struct. With this, the simple MyBool type has all of the basic operations and operators.
Hopefully this post gives you a few tips that you can apply to your own code when defining higher-level types.
By now, most of you have written a small Swift app or experimented in the playground. You may even have experienced an error after you copied code from a playground into another file and wondered, “What is actually going on? What is the difference between a playground file, and other Swift source files?” This post will explain how Swift deals with the files in your project, and how global data is initialized. Files in an App A Swift app is composed of any number of files, each with the functions, classes, and other declarations that make up the app. Most Swift files in your app are order-independent, meaning you can use a type before it is defined, and can even import modules at the bottom of the file (although that is not recommended Swift style.) However, top-level code is not allowed in most of your Swift source files. For clarity, any executable statement not written within a function body, within a class, or otherwise encapsulated is considered top-level. We have this rule because if top-level code were allowed in all your files, it would be hard to determine where to start the program. Playgrounds, REPL, and Top-Level Code You may be wondering why the code below works perfectly in a playground. This example isn’t encapsulated in anything, so it must be top-level code: println("Hello world") The above single-line program works — with no additional code at all — because playground files do support the execution of top-level code. Code within a playground file is order-dependent, run in top-down lexical order. For example, you can’t use a type before you define it. Of course, Swift playground files can also define functions, classes, and any other legal Swift code, but they don’t need to.
This makes it easy to learn the Swift language or try a new API without writing a lot of code to get started. In addition to playgrounds, top-level code can also be run in the REPL (Read-Eval-Print-Loop) or when launching Swift files as scripts. To use Swift for scripting, you can use shebang-style launching by starting your Swift file with “#!/usr/bin/xcrun swift” or type “xcrun swift myFile.swift” within Terminal. Application Entry Points and “main.swift” You’ll notice that earlier we said top-level code isn’t allowed in most of your app’s source files. The exception is a special file named “main.swift”, which behaves much like a playground file, but is built with your app’s source code. The “main.swift” file can contain top-level code, and the order-dependent rules apply as well. In effect, the first line of code to run in “main.swift” is implicitly defined as the main entrypoint for the program. This allows the minimal Swift program to be a single line — as long as that line is in “main.swift”. In Xcode, Mac templates default to including a “main.swift” file, but for iOS apps the default for new iOS project templates is to add @UIApplicationMain to a regular Swift file. This causes the compiler to synthesize a main entry point for your iOS app, and eliminates the need for a “main.swift” file. Alternatively, you can link in an implementation of main written in Objective-C, common when incrementally migrating projects from Objective-C to Swift. Global Variables Given how Swift determines where to start executing an app, how should global variables work? In the following line of code, when should the initializer run? var someGlobal = foo() In a single-file program, code is executed top-down, similar to the behavior of variables within a function.
Pretty simple. The answer for complex apps is less obvious, and we considered three different options:
Restrict initializers of global variables to be simple constant expressions, as C does. Allow any initializer, run as a static constructor at app load time, as C++ does. Initialize lazily, run the initializer for a global the first time it is referenced, similar to Java.
The first approach was ruled out because Swift doesn’t need constant expressions like C does. In Swift, constants are generally implemented as (inlined) function calls.
And there are good reasons to use complex initializers, e.g. to set up singletons or allocate a dictionary. The second approach was ruled out because it is bad for the performance of large systems, as all of the initializers in all the files must run before the application starts up. This is also unpredictable, as the order of initialization in different files is unspecified. Swift uses the third approach, which is the best of all worlds: it allows custom initializers, startup time in Swift scales cleanly with no global initializers to slow it down, and the order of execution is completely predictable. The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as dispatch_once to make sure that the initialization is atomic.
This enables a cool way to use dispatch_once in your code: just declare a global variable with an initializer and mark it private. Summary Swift is designed to make it easy to experiment in a playground or to quickly build a script. A complete program can be a single line of code. Of course, Swift was also designed to scale to the most complex apps you can dream up. With “main.swift” you can take complete control over initialization or you can let @UIApplicationMain do the startup work for you on iOS.
Objective-C and C APIs often require the use of pointers. Data types in Swift are designed to feel natural when working with pointer-based Cocoa APIs, and Swift automatically handles several of the most common use cases for pointers as arguments. In this post we’ll look at how pointer parameters in C can be used with the variables, arrays, and strings in Swift. Pointers as In/Out Parameters C and Objective-C don’t support multiple return values, so Cocoa APIs frequently use pointers as a way of passing additional data in and out of functions. Swift allows pointer parameters to be treated like inout parameters, so you can pass a reference to a var as a pointer argument by using the same & syntax. For instance, UIColor’s getRed(_:green:blue:alpha:) method takes four CGFloat* pointers to receive the components of the color. We can use & to collect these components into local variables: var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a) Another common case is the Cocoa NSError idiom. Many methods take an NSError** parameter to save an error in case of failure. For instance, we can list the contents of a directory using NSFileManager’s contentsOfDirectoryAtPath(_:error:) method, saving the potential error directly to an NSError? variable: var maybeError: NSError?
if let contents = NSFileManager.defaultManager()
.contentsOfDirectoryAtPath("/usr/bin", error: &maybeError) {
} else if let error = maybeError {
} For safety, Swift requires the variables to be initialized before being passed with &. This is because it cannot know whether the method being called tries to read from a pointer before writing to it. Pointers as Array Parameters Pointers are deeply intertwined with arrays in C, and Swift facilitates working with array-based C APIs by allowing Array to be used as a pointer argument. An immutable array value can be passed directly as a const pointer, and a mutable array can be passed as a non-const pointer argument using the & operator, just like an inout parameter. For instance, we can add two arrays a and b using the vDSP_vadd function from the Accelerate framework, writing the result to a third result array: import Accelerate
let a: [Float] = [1, 2, 3, 4]
let b: [Float] = [0.5, 0.25, 0.125, 0.0625]
var result: [Float] = [0, 0, 0, 0]
vDSP_vadd(a, 1, b, 1, &result, 1, 4)
Pointers as String Parameters C uses const char* pointers as the primary way to pass around strings. A Swift String can be used as a const char* pointer, which will pass the function a pointer to a null-terminated, UTF–8-encoded representation of the string. For instance, we can pass strings directly to standard C and POSIX library functions: puts("Hello from libc")
let fd = open("/tmp/scratch.txt", O_WRONLY|O_CREAT, 0o666)
if fd & 0 {
perror("could not open /tmp/scratch.txt")
let text = "Hello World"
write(fd, text, strlen(text))
} Safety with Pointer Argument Conversions Swift works hard to make interaction with C pointers convenient, because of their pervasiveness within Cocoa, while providing some level of safety. However, interaction with C pointers is inherently unsafe compared to your other Swift code, so care must be taken. In particular:
These conversions cannot safely be used if the callee saves the pointer value for use after it returns. The pointer that results from these conversions is only guaranteed to be valid for the duration of a call. Even if you pass the same variable, array, or string as multiple pointer arguments, you could receive a different pointer each time. An exception to this is global or static stored variables. You can safely use the address of a global variable as a persistent unique pointer value, e.g.: as a KVO context parameter. Bounds checking is not enforced when a pointer to an Array or String is passed. A C-based API can’t grow the array or string, so you must ensure that the array or string is of the correct size before passing it over to the C-based API. If you need to work with pointer-based APIs that don’t follow these guidelines, or you need to override Cocoa methods that accept pointer parameters, then you can work directly with raw memory in Swift using unsafe pointers. We’ll look at a more advanced case in a future post.
In Xcode 6 beta 4, Swift adds support for access control. This gives you complete control over what part of the code is accessible within a single file, available across your project, or made public as API for anyone that imports your framework. The three access levels included in this release are:
private entities are available only from within the source file where they are defined. internal entities are available to the entire module that includes the definition (e.g. an app or framework target). public entities are intended for use as API, and can be accessed by any file that imports the module, e.g. as a framework used in several of your projects.
By default, all entities have internal access. This allows application developers to largely ignore access control, and most Swift code already written will continue to work without change. Your framework code does need to be updated to define public API, giving you total control of the exposed interface your framework provides. The private access level is the most restrictive, and makes it easy to hide implementation details from other source files. By properly structuring your code, you can safely use features like extensions and top-level functions without exposing that code to the rest of your project. Developers building frameworks to be used across their projects need to mark their API as public. While distribution and use of 3rd-party binary frameworks is not recommended (as mentioned in a previous blog post), Swift supports construction and distribution of frameworks in source form. In addition to allowing access specification for an entire declaration, Swift allows the get of a property to be more accessible than its set. Here is an example class that is part of a framework: public class ListItem {
public var text: String
public var isComplete: Bool
private(set) var UUID: NSUUID
public init(text: String, completed: Bool, UUID: NSUUID) {
self.text = text
self.isComplete = completed
self.UUID = UUID
func refreshIdentity() {
self.UUID = NSUUID()
public override func isEqual(object: AnyObject?) -& Bool {
if let item = object as? ListItem {
return self.UUID == item.UUID
return false
} When mixing Objective-C and Swift, because the generated header for a framework is part of the framework’s public Objective-C interface, only declarations marked public appear in the generated header for a Swift framework. For applications, the generated header contains both public and internal declarations.
For more information,
books have been updated to cover access control. .
When designing Swift we made a key decision to do away with the C preprocessor, eliminating bugs and making code much easier to understand. This is a big win for developers, but it also means Swift needs to implement some old features in new ways.
Most of these features are obvious (importing modules, conditional compilation), but perhaps the most interesting one is how Swift supports macros like assert(). When building for release in C, the assert() macro has no runtime performance impact because it doesn’t evaluate any arguments.
One popular implementation in C looks like this: #ifdef NDEBUG
#define assert(e)
#define assert(e)
((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__)))
#define __assert(e, file, line) \
((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort())
#endif Swift’s assert analog provides almost all of the functionality of C’s assert, without using the preprocessor, and in a much cleaner way.
Let’s dive in and learn about some interesting features of Swift. Lazy Evaluation of Arguments When implementing assert() in Swift, the first challenge we encounter is that there is no obvious way for a function to accept an expression without evaluating it.
For example, say we tried to use: func assert(x : Bool) {
#if !NDEBUG
} Even when assertions are disabled, the application would take the performance hit of evaluating the expression: assert(someExpensiveComputation() != 42) One way we could fix this is by changing the definition of assert to take a closure: func assert(predicate : () -& Bool) {
#if !NDEBUG
if !predicate() {
} This evaluates the expression only when assertions are enabled, like we want, but it leaves us with an unfortunate calling syntax: assert({ someExpensiveComputation() != 42 }) We can fix this by using the Swift @autoclosure attribute.
The auto-closure attribute can be used on an argument to a function to indicate that an unadorned expression should be implicitly wrapped in a closure to the function.
The example then looks like this: func assert(predicate : @autoclosure () -& Bool) {
#if !NDEBUG
if !predicate() {
} This allows you to call it naturally, as in: assert(someExpensiveComputation() != 42) Auto-closures are a powerful feature because you can conditionally evaluate an expression, evaluate it many times, and use the bound expression in any way a closure can be used.
Auto-closures are used in other places in Swift as well.
For example, the implementation of short-circuiting logical operators looks like this: func &&(lhs: BooleanType, rhs: @autoclosure () -& BooleanType) -& Bool {
return lhs.boolValue ? rhs().boolValue : false
} By taking the right side of the expression as an auto-closure, Swift provides proper lazy evaluation of that subexpression. Auto-Closures As with macros in C, auto-closures are a very powerful feature that must be used carefully because there is no indication on the caller side that argument evaluation is affected.
Auto-closures are intentionally limited to only take an empty argument list, and you shouldn’t use them in cases that feel like control flow. Use them when they provide useful semantics that people would expect (perhaps for a “futures” API) but don’t use them just to optimize out the braces on closures. This covers one special aspect of the implementation of assert in Swift, but there is more to come.
The Swift programming language continues to advance with each new Xcode 6 beta, including new features, syntax enhancements, and behavioral refinements. Xcode 6 beta 3 incorporates some important changes, a few of which we’d like to highlight:Array has been completely redesigned to have full value semantics to match the behavior of Dictionary and String. Now a let array is completely immutable, and a var array is completely mutable.Syntax “sugar” for Array and Dictionary has changed. Arrays are declared using [Int] as short hand for Array&Int&, instead of Int[]. Similarly, Dictionary uses [Key: Value] for Dictionary&Key, Value&.The half-open range operator has been changed from .. to ..& to make it more clear alongside the ... operator for closed ranges. Xcode 6 beta is free to Registered Apple Developers and can be downloaded on the . Read all about these and other changes in the complete
One of the most common questions we heard at WWDC was, “What is the compatibility story for Swift?”. This seems like a great first topic. App Compatibility Simply put, if you write a Swift app today and submit it to the App Store this Fall when iOS 8 and OS X Yosemite are released, you can trust that your app will work well into the future. In fact, you can target back to OS X Mavericks or iOS 7 with that same app. This is possible because Xcode embeds a small Swift runtime library within your app’s bundle. Because the library is embedded, your app uses a consistent version of Swift that runs on past, present, and future OS releases. Binary Compatibility and Frameworks While your app’s runtime compatibility is ensured, the Swift language itself will continue to evolve, and the binary interface will also change. To be safe, all components of your app should be built with the same version of Xcode and the Swift compiler to ensure that they work together. This means that frameworks need to be managed carefully. For instance, if your project uses frameworks to share code with an embedded extension, you will want to build the frameworks, app, and extensions together. It would be dangerous to rely upon binary frameworks that use Swift — especially from third parties. As Swift changes, those frameworks will be incompatible with the rest of your app. When the binary interface stabilizes in a year or two, the Swift runtime will become part of the host OS and this limitation will no longer exist. Source Compatibility Swift is ready to use today, in brand new apps or alongside your proven Objective-C code. We have big plans for the Swift language, including improvements to syntax, and powerful new features. And as Swift evolves, we will provide tools in Xcode to help you migrate your source code forward. We can’t wait to see what you build!
This new blog will bring you a behind-the-scenes look into the design of the Swift language by the engineers who created it, in addition to the latest news and hints to turn you into a productive Swift programmer.Get started with Swift by downloading , now available to all Registered Apple Developers for free. The Swift Resources tab has a ton of great links to videos, documentation, books, and sample code to help you become one of the world’s first Swift experts. There’s never been a better time to get coding!- The Swift Team
(1-800-MY-APPLE), visit an , or find a .
Copyright (C) 2014 Apple Inc. All rights reserved.}

我要回帖

更多关于 namevaluepair 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信