10 Swift Features That Aren’t in Objective-C
Objective‐C dates back to the 1980s — quite a long time ago by computer technology standards. In the decades since its first release, Objective‐C’s influence on programming language technologies and best practices (along with hardware and operating system changes) has demonstrated that the Objective‐C design is robust and flexible. With the dawn of a new century, Apple’s engineers embarked on the development of a new language for today’s technology world.
As of this writing, Objective‐C and Swift are both available to developers. Both let you work with the Cocoa and Cocoa Touch frameworks. In all likelihood, Objective‐C one day will be replaced by Swift, but this won’t happen quickly. Even with Swift’s shorter learning curve, the transition from Objective‐C to Swift will be measured in years.
For now, developers can work in either language. Most of the frameworks are still written in Objective‐C, so even if you write your code in Swift, you will need to interact with Objective‐C frameworks. Fortunately, this isn’t difficult.
This list covers ten Swift features that aren’t available in Objective‐C. As you switch back and forth between the two languages, this list may help you distinguish between the features available in each language. In general, of course, you can rely on Swift to follow one overall theme: With Swift, you’ll frequently write less code. This is because the Swift language is designed to handle a number of Objective‐C’s common situations all by itself.
Before getting to Swift features that aren’t in Objective‐C, here are three terms common to both languages that have slightly different meanings in Swift:
closure: In Swift, a closure is a section of code that can be executed non‐sequentially. It’s declared with its own variables (and references variables available in the scope in which it’s created), and it’s executed when needed. Closures are frequently used as completion handlers for asynchronous processes, so whenever that process completes (even if completion is a failure), the closure will run. Swift considers a function to be a special case of a closure. Closures in Swift are similar to blocks in Objective‐C.
type: In Swift, a type can be a class, structure, or enumeration. Any of these can contain methods. functions, and members.
pass by reference/pass by value: Passing variable back and forth is a classic issue in object‐oriented programming. In Swift, structures and enumerations are passed back and forth by value (or by copying — the same thing). This means that the same value can be passed to several places, and in each place, it can be used and modified without affecting any of the other occurrences.
Class instances in Swift are passed by reference so that a single version of the instance is referenced by all clients. If there are multiple instances of a class, each of those instances is passed around by reference. Objective‐C deals with these issues in different ways such as by referring to strong and weak references.
Using playgrounds to explore code and syntax
Playgrounds are a new feature of Xcode 6 that let you test code easily. They can make writing your code very much like writing code for an interpreted language because you see the results immediately. You can do the same with your code — you don’t have to get a clean compile and build to get down to testing how a single line of code works (or doesn’t work).
Tuples let you group individual values into a single unit. In Objective‐C, this is often done with dictionaries that organize multiple values together. When the multiple values have a logical organizing principle, consider using tuples for cleaner and more easily understood code.
Using ranges to save code
Like tuples, ranges let you create reusable constructs that can be used in creating and using functions. They generally replace small sections of code. By naming and reusing them, you can avoid the typographical errors often introduced by retyping the same code several times.
Taking advantage of strict typing and type safety
Unlike other languages, including Objective‐C, Swift makes you handle type conversion and casting explicitly. Among other things, this gets rid of pesky errors that arise when the compiler and operating system convert a value from one type to another (and you were thinking that the conversion would not take place or would be a different type of conversion).
Now, you are responsible for the conversions, and the compiler and operating system do your bidding instead of sometimes surprising you.
Initializing your variables and constants
Although you may not always realize it, Swift requires that each property be initialized either with an explicit value and an explicit type annotation, or with an inferred type based on an explicit value.
Understanding optional types
Swift requires that you type properties explicitly or by providing a value whose type Swift can infer. Swift gives you a number of tools that can type a property as optional. Optional types let Swift know that you have thought about a type, but you haven’t yet reached a final conclusion about it. With an optional type, you provide enough information for Swift to keep going.
Looking at frameworks for your own code
When developing apps, you’ll constantly use Cocoa and Cocoa Touch frameworks. The frameworks used tend to be very large — UIKit is an example — but with Swift, Apple provides sample code that takes advantage of a number of very small custom frameworks.
By combining the framework architecture and Swift’s simplicity, you have a convenient way to construct your own apps and reuse code. When you start to explore Swift, make frameworks one of your first stops.
Including annotations and attributes in declarations
The format of declarations has changed significantly in Swift. The original format of declarations consisted of two parts:
This style dates back to the early days of FORTRAN. Over the years, additions and decorators were added. Now, with Swift, this core syntax has been replaced with annotations and attributes that are more flexible.
Deinitializing variables where necessary
Swift manages memory, and you can rely on it to clean up as needed when you (or the system) deallocates an instance. You can write a deinitializer (named deinit) to do anything other than simple memory releasing. Among the tasks a deinitializer might do are closing a file and placing a data structure in a known state for its next use, among similar tasks.
Use patterns to simplify your code
You can specify cases inside a switch statement that consist of patterns. This can get rid of a good deal of code because in addition to switching on values, you can switch on ranges of data as well as conditions and characteristics of data that go beyond individual values.