Date post: | 22-Apr-2018 |
Category: |
Documents |
Upload: | nguyencong |
View: | 217 times |
Download: | 2 times |
CocoaHeads Köln, July 2014
SwiftModern, Safe, Fast?, Beta!
by Joachim Kurz (@cocoafrog)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift
Theory
staticM
ore static than Objective-C
compiled not interpreted
Type Inference
Object-O
riented
Functional
Generic
what type of generic? There w
as a technical term
. Opposite of „type
erasure“
Advanced
Enums w
ith associated values
value type can be different for each m
ember of the enum
eration (B1: p. 143)
other names: „discrim
inated unions“, „tagged unions“, „variants“
Pattern matching
normal sw
itch
combine several cases together
but in that case no value bindings
no automatic fall-through, only
explicit
must be exhaustive (use default if in
doubt)
switch over strings
switch over Any type
via probably via ==
switch over ranges
switch by type
match tuple
use wildcard-operator `_`
partil type restrictions in tuples(x: String, y)
value bindings using let/var
match associated value of enum
complex patterns com
bined from
all of the above
guard expression: can specify arbitrary additional checks w
ith `w
here`
overload ~= operator to extend pattern m
atching
ARC in Swift
strong by default
weak-references
use whenever it is valid to becom
e nil during lifetim
e
always O
ptional<>
unowned references
use when reference w
ill never be nil once it has been set during initialization
similar to unsafe unretained
accessing an unowned reference
after the referenced instance is deallocated is a runtim
e error
App will alw
ays crash when
unowned deallocated instance is
referenced. => Safer than unsafe unretained
capture lists in closures
Closures
variables can be changed by default (like __block in O
bjective-C). But sim
ply use let instead.
Use closures to initialize properties w
ith more com
plex calculations
user @lazy properties w
hen referring to self (can’t refer to self in a property-initializing non-lazy closure, as self is not yet initialized at that point in tim
e)
initializers
designated initializersm
ust call super-types initcorrect initialization order
1. initialize own properties
2. call super.init
3. modify properties of superclass
and call instance methods
convenience initializersm
ust call across to self.initcorrect initialization order
1. call self.init
2. modify properties of superclass
and call instance methods
default initializersif all properties initialized: zero-argum
ent-init
structs: all-arguments init
Initializer inheritance
if all properties initialized: zero-argum
ent-init
if all designated initializers override: inherit convenience initializers
required-attributeforces subclass to override it
Variables
computed variables
lazy variables
global variables are always lazy
Special attributes@
auto_closure
@lazy
optional chaining
testing if methods exists
functions without a return-type
have an implicit return type of Void/
(). That means their optional-
chaining return-type is Void? and can thus be used to see w
hether the function w
as called. (B1, p.253)
Extensions
can extend every type of Swift,
even structs, enums and e.g. Int
(which is just a struct)
add functionality to the original type, that w
asn’t there before (like Categories)
add protocol conformance
Operators
Operator O
verloading
Ow
n Operators
Basics
let und var
Type syntax
Function syntax
Return type with arrow
Parameters
Local and external parameter
names
initializer
automatic external param
eter nam
es for every parameter
can use _ to prevent an external param
eter name. But shouldn’t.
functions
parameter nam
es are not used for calling by default. Can specify external param
eter names explicitly
or use same as internal w
ith `#` prefix
methods
all parameter nam
es are requied, except first that is assum
ed
Can declare a parameters as var to
allow code to change it inside the
variable
can annotate with spoeicla „inout“
keyword that m
akes changes to the variable propagate tp the calling site.
default values for parameters
example: NSLocalizedString w
ith default values for bundle and table
variadic parameters
given as array to function
Nested functions
override keyword
static/class methods
Types
Classes
Structs
Enums
Difference between Classes,
Structs and Enums
All
can adopt protocols
can have methods
can have properties
can use generics
Reference-Types and Value TypesConstant behaviour
special „mutating“ functions
Copying behaviour
Inheritance
Static properties
Basic Initialization
Protocolscan only have optional m
ethods if m
arked with @
objcthis can only be adopted by classes
can even specify initializers
Properties
Stored Properties
Lazy Properties
Computed Properties
Optionals
nil is a special value for every type, „norm
al“ values for a type can’t be nil
use three examples of functions to
show w
hy making optionality
explicit is a good thing
stringByAppendingString: crashes w
hen given „nil“
indexOfO
bject: returns NSNotFound w
hen the collection does not contain the object
if-let
? operator
! operator
if-let
optional-chainingresult of optional chaining is alw
ays an optional, but at m
ost one level of optionality is added (B1, p.255)
Casting
ischeck w
hether it is of that type
as?cast if of that type (therefore return type optional)
asforced cast
can cast complete collections, e.g.
[AnyObject] as [Car]
also work for checking for protocol
conformance
but only if marked w
ith @objc
Nested TypesCan define other types inside of type definition (B1, p.266)
Types
static properties
dynamicType
like -class in Objective-C, returns
the Type of an object/value
.selfAs in `Array.self`
typealiastyepalias nam
e = existingType
Beta
Still slow
Syntax still changes.. becam
e ..<
Semantics still change
Constant arrays are now com
pletely constant but w
eren’t at first
Character is said to support com
plete graphemes soon
Missing features
access control: private/public
Reflection?
KVO?
Functional Programm
ing
Higher Order Functions
Closures
Lazy-Evaluation of SequencesInfinite Sequence of Fibonacci num
bers
Currying
What do w
e loose?
no performSelector:
but @selector is available, e.g. for
setTarget:action:
KVC and KVO?
Message Passing
partially enabled if subclass of NSO
bject
Polymorphism
Subtyping/Dynamic Polym
orphism
overriding of methods, as in
Objective-C
single dispatch
dynamic dispatch/late binding
Ad Hoc Polymorphism
/Function overloading based on param
eters
overloading functions as in Java
compile tim
e/early binding
Also polymorphism
on return typenot possible in Java
Generic Program
ming
Generic program
ming is a program
ming
method that is based in finding the m
ost abstract representations of efficient algorithm
s. http://ww
w.stlport.org/
resources/StepanovUSA.htm
l
„find the [generic] data structure inside an algorithm
“ instead of „find the [virtual] algorithm
s inside an object“ http://w
ww
.stlport.org/resources/StepanovU
SA.html
Examples
swap
template<typename T>
void Swap(T & a, T & b) //„&“
passes parameters by reference
{ T temp = b;
b = a;
a = temp;
} string hello = „world!“, world =
„Hello, „;
Swap( world, hello );
cout << hello << world << endl; //
Output is „Hello, world!“
max
Generic Collections
Generic Protocols
Associated Types (only defined later)
difference to generic parameter:
has to be specified by subtypes
http://en.wikipedia.org/w
iki/G
eneric_programm
ing
Limitations in Sw
ift
Subclasses of generic classes must
also be generic
Cannot modify generic param
eter in subclass
e.g. Bag<T:Comparable> extends
Array<T>
Performance
Swift internals
Primitive types are also structs
vtable instead of dynamic dispatch
more com
piler optimizations
possible because of more
constants and less unclear pointers
Measurem
ents
Simple Loop (100_000_000)
var temp:UInt32 = 0 for (var i = 0; i <= 100_000_000; i++) { temp ^= 12345678 } result = temp
-Os/ -O
C: 0.030
Swift: 0.059
-Ofast
C: 0.011
Swift: 0.011
Sum of Array
int temp = 0; for (int i = 0; i < count; i++) { temp += numbers[i]; } result = temp;
-Os/ -O
C: 0.055
Swift-for-loop: 1.712
Swift-for-in-loop: 5.136
Swift-reduce: 4.961
Objective-C-for-loop: 2.418
Objective-C-fast-enum
eration: 1.210
-Ofast
C: 0.028
Swift-for-loop: 0.058
Swift-for-in-loop: 0.156
Swift-reduce: 0.072
Objective-C-for-loop: 2.459
Objective-C-fast-enum
eration: 1.211
Create array with fixed values
Array(count: HUNDRED_MILLION, repeatedValue:42)
-Os/ -O
Swift: 0.471
Objective-C-for-loop: 4.320
-Ofast
Swift:
Objective-C-for-loop: 2.459
Sort Simple Array
-Os/ -O
Swift-for-loop: 1.712
Swift-for-in-loop: 5.136
Swift-reduce: 4.961
Objective-C-for-loop: 2.418
Objective-C-fast-enum
eration: 1.210
-Ofast
Swift-for-loop: 1.712
Swift-for-in-loop: 5.136
Swift-reduce: 4.961
Objective-C-for-loop: 2.418
Objective-C-fast-enum
eration: 1.210
Swift and O
bjective-C
Much safer than O
bjective-C and C
„1
3 of the security issues fi
xed in 1
0.9
.4 could
have b
een prevented
or mitigated
by Sw
ift (9
buff
er overruns, 2 int und
er/overflow
s, 2 null
derefs). T
hat alone makes it w
orth it from m
y point of view
.“http
s://devforum
s.apple.com
/message/
10
07
09
3#
10
07
09
3
Advanced Swift
Basic Swift
Func
tiona
l Pro
gram
min
g
Gen
eric
Pro
gram
min
g
Beta
What’s lost?Performance
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
NSString *s = @"foo"; [s characterAtIndex:@"bar"];
Objective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
NSString *s = @"foo"; [s characterAtIndex:@"bar"];
Objective-C
Warningand you can even cast it and it works! 👎
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
NSString *s = @"foo"; [s characterAtIndex:@"bar"];
Objective-C
var s:NSString = "foo" s.characterAtIndex("bar")
Swift
Warning Compiler Error 👍and you can even cast it and it works! 👎 Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
Alt-Click variable to get inferred type info
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
• Object-Oriented
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
• Object-Oriented
• Functional
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
• Object-Oriented
• Functional
• Generic
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
• Object-Oriented
• Functional
• Generic
• Generally much safer than Objective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Overview• Static typing: Much more than Objective-C
• Compiled, not interpreted
• Type Inference
• Multi-Paradigm
• Object-Oriented
• Functional
• Generic
• Generally much safer than Objective-C
„13 of the [20] security issues fixed in 10.9.4 could have been prevented or mitigated by Swift (9 buffer overruns,
2 int under/overflows, 2 null derefs).“ CFM in Apple Developer Forums
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Hello World
println("Hello World")
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Hello World
println("Hello World")
no imports no class definition
no main() functionno header file
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
• And no default fallthrough
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
• And no default fallthrough
• No more Format Strings
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
• And no default fallthrough
• No more Format Strings
• No Preprocessor Macros
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
• And no default fallthrough
• No more Format Strings
• No Preprocessor Macros
• Must explicitly mark overridden methods
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift as „Fixing“ Objective-C• No more Header Files
• Namespaces = No more Class Prefixes
• Curly Brackets required around body of if/for/while
• switch over Strings (and a lot more)
• And no default fallthrough
• No more Format Strings
• No Preprocessor Macros
• Must explicitly mark overridden methods
Legacy
Expressive
Safe
Safe
Safe
Legacy
SafeLegacy
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Stayed Similarprotocol MyProt:NSObjectProtocol {} !class A : NSObject { var x = 2 weak var parent:A? } !var a = A() var array = NSArray(object: A()) array = [2,3,4] !var index = array.indexOfObject(A(), inRange:NSRange(0..<10)) !array.sorted({ return $0 < $1})
@protocol MyProt <NSObject> @end !@interface A : NSObject @property (assign) NSInteger x; @property (weak) A *parent; @end !A *a = [[A alloc] init]; NSArray *array = [NSArray arrayWithObject:a]; array = @[@2, @3, @4]; !NSUInteger index = [array indexOfObject:a inRange:NSMakeRange(0, 10)]; ![array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2]; }];
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
let and varclass A { let b = 0 let c:String let d:String init() { c = „Hello" } } var a = A() a.b = 3 a.d = 5.0
❗️
❗️
var x = 2 let y = 2 x = 3 y = 3
❗️can’t assign constant twice
can’t assign constant after init
must init constant d
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
let in struct and classstruct Astruct { var x = 1; } !class Aclass { var x = 1; } !let constStructA = Astruct() var varStructA = Astruct() let constObjectA = Aclass() !constObjectA.x = 2 varStructA.x = 2 constStructA.x = 2❗️
• can assign var-property of constant object
• can assign var-property of var-struct
• can not modify constant struct in any way
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Array and Dictionary are structs
let constNumbers = [1,2,3] var varNumbers = [1,2,3] !
let constLegsByAnimal = ["spider" : 8, "dog" : 4, "swift" : 2] var varLegsByAnimal = ["spider" : 8, "dog" : 4, "swift" : 2] !
varNumbers[1] = 0 varLegsByAnimal["spider"] = 7 !
constNumbers[1] = 0 constLegsByAnimal["spider"] = 7
❗️❗️
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
structs can have methods
struct MyRect { var origin = CGPoint() var size = CGSize() func area() -> Double { return size.height * size.width } }
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
structs can have methods
struct MyRect { var origin = CGPoint() var size = CGSize() func moveBy(x: CGFloat, y:CGFloat) { origin.x += x origin.y += y } }
❗️❗️
cannot modify properties of struct from „normal“ method => need mutating keyword
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Methods that change Properties are marked as mutating
var a = MyRect() let b = MyRect() !
a.moveBy(0, y: 1); b.moveBy(0, y: 1);
struct MyRect { var origin = CGPoint() var size = CGSize() mutating func moveBy(x: CGFloat, y:CGFloat) { origin.x += x origin.y += y } }
❗️
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Enums can have Methods, tooenum Color { case Red, Blue, Green, Orange, Yellow func isWarmColor() -> Bool { return (self == Red) || (self == Orange) || (self == Yellow) } mutating func makeColdColor() { if (self.isWarmColor()) { self = (random()%2 == 0) ? .Blue : .Green } } } !var varColor = Color.Green varColor.makeColdColor() !let aColor = Color.Red aColor.isWarmColor() aColor.makeColdColor()❗️
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enum
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
Subscript ✔ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
Subscript ✔ ✔ ✔
Inheritance ✔ ❌ ❌
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
Subscript ✔ ✔ ✔
Inheritance ✔ ❌ ❌
Deinitializer ✔ ❌ ❌
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
Subscript ✔ ✔ ✔
Inheritance ✔ ❌ ❌
Deinitializer ✔ ❌ ❌
Check protocol conformance at runtime ✔ ❌ ❌
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Difference class, struct, enumclass struct enum
Passed around by reference by value (copied) by value (copied)Methods ✔ ✔ ✔
Initializer ✔ ✔ ✔
Conform to Protocol ✔ ✔ ✔
Be extended ✔ ✔ ✔
Generics ✔ ✔ ✔
Modify if let ✔ ❌ ❌
Stored Properties ✔ ✔ ❌
Computed Properties ✔ ✔ ✔
Subscript ✔ ✔ ✔
Inheritance ✔ ❌ ❌
Deinitializer ✔ ❌ ❌
Check protocol conformance at runtime ✔ ❌ ❌
Stored static properties ❌ ✔ ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
optional
⎧ |
! | ⎨
|
! | ⎩⎧
|
|
|
|
|
|
|
|
! | ⎨
|
|
|
|
|
|
|
|
! | ⎩
optional
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
func anotherFunction() -> Bool { return true }
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
func anotherFunction() -> Bool { return true }
func functionNoReturnNoParam() {}
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
func anotherFunction() -> Bool { return true }
func functionTuple() -> (Int, String) { return (42, "what?") }
func functionNoReturnNoParam() {}
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
func anotherFunction() -> Bool { return true }
func functionTuple() -> (Int, String) { return (42, "what?") }
func functionWithDefaultValue(x:Int = 2) {}
func functionNoReturnNoParam() {}
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functionsfunc myFunction(aNumber: Int, aString:String) -> Bool { return true }
func name(param1: Type, param2:Type, ...) -> ReturnType
func otherFunction(aNumber: Int) {}
func anotherFunction() -> Bool { return true }
func functionTuple() -> (Int, String) { return (42, "what?") }
func functionWithDefaultValue(x:Int = 2) {}
func functionVarParam(x:Int, ps:String...) -> Int { return ps.count }
func functionNoReturnNoParam() {}
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names
func myFunction(aNumber: Int, aString:String) -> Bool { return true }
myFunction(2, "foo")
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Functions
func multiply(number lhs: Int, by rhs:Int) -> Int { return lhs * rhs }
multiply(number: 2, by: 5)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Use # for shorthand parameters
func multiply(#number: Int, #by:Int) -> Int { return number * by }
multiply(number: 2, by: 5)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: default parameters always externalfunc multiply(number: Int, by:Int = 2) -> Int { return number * by }
multiply(2, by: 5)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Initializer - external by default
class Car { var speed = 0.0 var age = 0.0 init(speed: Double) { self.speed = speed } init(ageInYears age: Double) { self.age = age } }
var myCar = Car(ageInYears: 3.5);
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Use _ to deactivate it
struct Length { var value: Int init (_ value: Int) { self.value = value } }
var length = Length(2)
Only use this if the meaning of the parameter is completely obvious!
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Methods
class Car { var speed = 0.0 func accelerateToSpeed(targetSpeed: Double, overTime:NSTimeInterval) { } }
var myCar = Car() myCar.accelerateToSpeed(100.0, overTime: 10.0)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
External Parameter Names: Summary
Functions no external parameter names by default
Initializers all parameters external by default
Methods first parameter not external, other parameters external by default
• # to use same name for internal and external name
• _ to remove default external parameter name
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals
Introducing Null-References was a „billion dollar mistake“
Tony Hoare, inventor of quicksort, Hoare logic, CSP, Occam
about introducing Null-References to ALGOL W in 1965
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals2 of the 20 security issues fixed in 10.9.4 were
null-dereferencesGraphics Drivers
Available for: OS X Mountain Lion v10.8.5, OS X Mavericks 10.9 to 10.9.3
Impact: A malicious application may be able to execute arbitrary code with system privileges
Description: Multiple null dereference issues existed in kernel graphics drivers. A maliciously crafted 32-bit executable may have been able to obtain elevated privileges.
CVE-ID
CVE-2014-1379 : Ian Beer of Google Project Zero
IOReporting
Available for: OS X Mavericks 10.9 to 10.9.3
Impact: A local user could cause an unexpected system restart
Description: A null pointer dereference existed in the handling of IOKit API arguments. This issue was addressed through additional validation of IOKit API arguments.
CVE-ID
CVE-2014-1355 : cunzhang from Adlab of Venustech
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!No Crash, but returns nil !
and likely leads to crash later
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
Crash!
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
Crash! OK ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
Crash! OK ✔ OK ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhich of these functions can take nil/NULL?
[@"foo" stringByAppendingString:nil];
[managedObjectContext objectWithID:nil];
dispatch_async(dispatch_get_main_queue(), NULL);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:nil parameters:nil success:nil failure:nil];
[NSURL URLWithString:nil];
Crash!
Crash!
Crash!
No Crash, but returns nil !and likely leads to crash later
Crash! OK ✔ OK ✔ OK ✔
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhat’s wrong here?
NSArray *results = [managedObjectContext executeFetchRequest:theFetchRequest error:NULL]; NSUInteger index = [results indexOfObject:objectToFind]; return results[index];
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhat’s wrong here?
NSArray *results = [managedObjectContext executeFetchRequest:theFetchRequest error:NULL]; NSUInteger index = [results indexOfObject:objectToFind]; return results[index];
Crash! Index Out Of Bounds
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
OptionalsWhat’s wrong here?
NSArray *results = [managedObjectContext executeFetchRequest:theFetchRequest error:NULL]; NSUInteger index = [results indexOfObject:objectToFind]; return results[index];
Crash! Index Out Of Bounds• Problem: NSNotFound returned
• used a special value of the same type as error marker
➡ Compiler has no chance to find that error
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals• In Swift a standard variable cannot be nil!
var foo:String = nil❗️ Compiler Error 👍
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals• In Swift a standard variable cannot be nil!
• Use special Type-Variant that allows nil
Safe
var foo:String? = nilvar bar:String = "bar" bar.stringByAppendingString(foo)❗️
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals• In Swift a standard variable cannot be nil!
• Use special Type-Variant that allows nil
• Also use special type variant in other cases where you need „does not exist“ values
Safe
var array = [2,3,4] var index = find(array, 5) var theObject = array[index]❗️
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optionals• In Swift a standard variable cannot be nil!
• Use special Type-Variant that allows nil
• Also use special type variant in other cases where you need „does not exist“ values
• You can wrap every single type in Swift in an Optional by just adding „?“ after the type.
• Use it only where it actually makes sense to be nil
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Using Optionals• use if to check whether value is nil
• use ! to unwrap value from optional
Safe
let array = [2,3,4] let index = find(array, 5) if (index) { let theObject = array[index!] println(theObject); }
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Using Optionals• use if to check whether value is nil
• use ! to unwrap value from optional
• can use it without if, will crash if nillet array = [2,3,4] let index = find(array, 4) let theObject = array[index!] println(theObject)
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Using Optionals• use if to check whether value is nil
• use ! to unwrap value from optional, will crash if nil
• use if-let to unwrap and check at the same timelet array = [2,3,4] let index = find(array, 5) if let checkedIndex = index { let theObject = array[checkedIndex] println(theObject); }
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Using Optionals• use if to check whether value is nil
• use ! to unwrap value from optional, will crash if nil
• use if-let to unwrap and check at the same time
let legsByAnimal = ["spider":8, "dog":4] if let numberOfLegs = legsByAnimal["dog"] { println(numberOfLegs) }
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optional Chaining• use ? to guard access to instances of optional
types
• return type becomes optional, if it wasn’t already
let animals = ["spider":["favoriteFood" : "Harry Potter", "name" : "Aragog"]] if let name = animals["spider"]?["name"] { println(name) }
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optional Chaining• also for optional methods
Safe
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optional Chaining• also for optional methods
Safe
@objc protocol HasName { @optional func name() -> String? } !class Spider : HasName { var name:String? init(name:String) { self.name = name } } !let spider:HasName? = Spider(name: "Aragog") if let firstTwoLetters = spider?.name?()?.substringToIndex(2) { println(firstTwoLetters) }
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optional Chaining• also for optional methods
Safe
@objc protocol HasName { @optional func name() -> String? } !class Spider : HasName { var name:String? init(name:String) { self.name = name } } !let spider:HasName? = Spider(name: "Aragog") if let firstTwoLetters = spider?.name?()?.substringToIndex(2) { println(firstTwoLetters) }
spider nil? has method name() name nil?
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Optional Chaining: Checking whether a method was called
• no return type = Void = ()
= empty tuple
• return type with optional chaining: Void? = ()?
➡ either nil or () ➡ can check it
Safe
@objc protocol CeilingWalker { @optional func walkOnCeiling() } !class Spider : CeilingWalker {} !let spider:CeilingWalker = Spider() if let didWalkOnCeiling:Void = spider.walkOnCeiling?() { println("The spider walked on the ceiling") } else { println("It didn't walk on the ceiling") }
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Theory (and Examples ;-) )
• Polymorphism
• single dispatch, late binding, function overloading
• Generic Programming
• Functional Programming
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism• Same method name, different implementations
• In Swift
• External Names
• Subtyping (Late Binding)
• Ad Hoc Polymorphism (Overloading)
• Parametric Polymorphism (Generic Programming)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: External Names• Each parameter has a name that can be used when the function is called
• Functions with same name but different parameter names are different functions
Objective-C Java C++ C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: External Names• Each parameter has a name that can be used when the function is called
• Functions with same name but different parameter names are different functions
Objective-C Java C++ C
func move(#point: CGPoint, to targetPoint:CGPoint) -> CGPoint { return targetPoint; } func move(#point: CGPoint, by vector:CGPoint) -> CGPoint { return CGPoint(x:point.x + vector.x, y:point.y + vector.y) } !var pointA = CGPoint(x: 2, y:4) var pointB = CGPoint(x: 3, y:5) !move(point: pointA, by: pointB) move(point: pointA, by: pointB)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: External Names• Each parameter has a name that can be used when the function is called
• Functions with same name but different parameter names are different functions
Objective-C Java C++ C
func move(#point: CGPoint, to targetPoint:CGPoint) -> CGPoint { return targetPoint; } func move(#point: CGPoint, by vector:CGPoint) -> CGPoint { return CGPoint(x:point.x + vector.x, y:point.y + vector.y) } !var pointA = CGPoint(x: 2, y:4) var pointB = CGPoint(x: 3, y:5) !move(point: pointA, by: pointB) move(point: pointA, by: pointB)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; !
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: Subtyping• Overriding a superclass method in the sublcass
• Late Binding: Method to call determined at runtime
• Single Dispatch: Only runtime type of callee is used, not runtime types of arguments
Objective-C Java C++ C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: Subtyping
Objective-C Java C++ C
class A { func calcNumber() -> Int { return 2 } } !
class B:A { override func calcNumber() -> Int { return 3 } } !
let bSavedInAVar:A = B() let result = bSavedInAVar.calcNumber() // result is 3
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: Ad Hoc / Function Overloading
• Functions/Methods with same parameter names but different types are different methods
• Compile Time Binding: Only the static time (at compile time) of the arguments is used
Objective-C Java C++ C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: Ad Hoc / Function Overloading
Objective-C Java C++ C
class A {} class B:A {} func calculateNumber(number: A) -> Int{ return 2 } !
func calculateNumber(number: B) -> Int { return 3 } !
let x = calculateNumber(A()) // result: 2 let y = calculateNumber(B()) // result: 3 let bAsA:A = B() let z = calculateNumber(bAsA) // result: 2
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Polymorphism: Function Overloading by Return Type
• Functions/Methods with same parameter names and types but different return types are different functions
Objective-C Java C++ C
class A {} class X {} func getObject() -> A { return A() } !func getObject() -> X { return X() } !let x:A = getObject() // result: A let y:X = getObject() // result: X
Demo: Polymorphism
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Programming
Alexander Stepanov!creator of the STL (Standard Template Library) for C++
in „An Interview with A. Stepanov“,
„Generic programming is a programming method that is based in
finding the most abstract representations of efficient algorithms.“
„find the [generic] data structure inside an algorithm“ instead of „find the
[virtual] algorithms inside an object“
„And if [the language] cannot implement max or swap or linear search, what chances do they have to
implement really complex stuff? These are my litmus tests: if a language allows me to implement max and swap and linear search generically - then it has some
potential.“
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Problem
func maxInt(number1:Int, number2:Int) -> Int { if number1 > number2 { return number1 } else { return number2 } } !
func maxDouble(number1:Double, number2:Double) -> Double { if number1 > number2 { return number1 } else { return number2 } }
Objective-C Java C++ C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Problem
func maxInt(number1:Int, number2:Int) -> Int { if number1 > number2 { return number1 } else { return number2 } } !
func maxDouble(number1:Double, number2:Double) -> Double { if number1 > number2 { return number1 } else { return number2 } }
Too m
uch Code Duplicatio
n!
Objective-C Java C++ C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Approach: Interfaces
func maxViaInterface(param1:Comparable, param2:Comparable) -> Comparable { if param1 > param2 { return param1 } else { return param2 } }
Java C++ C
*doesn’t actually compile in Swift, due to Self reference in protocol declaration, but would in Java or Objective-C
Objective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Approach: Interfaces
func maxViaInterface(param1:Comparable, param2:Comparable) -> Comparable { if param1 > param2 { return param1 } else { return param2 } }
Java C++ C
*doesn’t actually compile in Swift, due to Self reference in protocol declaration, but would in Java or Objective-C
Objective-C
BUT:
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Approach: Interfaces
func maxViaInterface(param1:Comparable, param2:Comparable) -> Comparable { if param1 > param2 { return param1 } else { return param2 } }
Java C++ C
*doesn’t actually compile in Swift, due to Self reference in protocol declaration, but would in Java or Objective-C
Objective-C
BUT:var x = maxViaInterface(2, 3) var y = maxViaInterface(2, "String")
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Approach: Interfaces
func maxViaInterface(param1:Comparable, param2:Comparable) -> Comparable { if param1 > param2 { return param1 } else { return param2 } }
Java C++ C
*doesn’t actually compile in Swift, due to Self reference in protocol declaration, but would in Java or Objective-C
Objective-C
BUT:var x = maxViaInterface(2, 3) var y = maxViaInterface(2, "String")
needs a cast to Int to be usable
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Approach: Interfaces
func maxViaInterface(param1:Comparable, param2:Comparable) -> Comparable { if param1 > param2 { return param1 } else { return param2 } }
Java C++ C
*doesn’t actually compile in Swift, due to Self reference in protocol declaration, but would in Java or Objective-C
Objective-C
BUT:var x = maxViaInterface(2, 3) var y = maxViaInterface(2, "String")
needs a cast to Int to be usableworks, but doesn’t make sense!
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Use Type Variable
func genericMax<T:Comparable>(param1:T, param2:T) -> T { if param1 > param2 { return param1 } else { return param2 } }
Java C++ CObjective-C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Max() function: Use Type Variable
func genericMax<T:Comparable>(param1:T, param2:T) -> T { if param1 > param2 { return param1 } else { return param2 } }
Java C++ CObjective-C
var x = genericMax(2, 3) // x is of type Int var y = genericMax(2, "String")❗️ Compiler Error 👍
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Swap() functionfunc genericSwap<T>(inout a:T, inout b:T) { let tempA = a a = b b = a } !
var x = 2 var y = 3 var z = "foo" !
genericSwap(&x, &y) println(x) // prints 3 !
genericSwap(&x, &z)
Java C++ CObjective-C
❗️ Compiler Error 👍
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generic Objects• Collections with specific Element Types
var numbers:Array<Int> = [2,3,4] var strings:Array<String> = ["hallo", "welt"] !
let x:Int = numbers[0] let word:String = strings[0] !
numbers.append("foo") word.append(2)❗️❗️
Compiler Error 👍 Compiler Error 👍
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Generics in Swift: Limitations• Subclasses of generic classes must also be
generic
• Cannot modify generic parameter in subclass
class MySpecialIntList : Array<Int> {} class MySpecialList<T:MySpecialProtocol> : Array<T> {}
these two declarations do not work in Swift (but e.g. Java)
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift: Generics Improvements• Types are kept at runtime
func printList<T:Collection>(list:T) { if (list is Array<Int>) { println("is an array of ints") } else { println("is not an array of ints") } } !
var intList = [2,3,4] printList(intList) // prints "is an array of ints"
Objective-C Java C++ C?
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Functional Programming• Functions are „First Class Objects“
• Can pass them as parameters
• Can store them in variables
• Anonymous functions
• Create functions on the fly
• Lambda, Closure, Blocks
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Higher Order Functions• Functions that operate on functions
func applyNTimes(#n: Int, to argument:Int, functionToApply f:Int->Int) -> Int { var result = argument for _ in 1...n { result = f(result) } return result } !func addTwo(a: Int) -> Int { return a + 2 } !var result = applyNTimes(n: 3, to: 10, functionToApply: addTwo) println(result) // prints 16
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Higher Order Functions on Collections
• map: Apply function to each element in a list and return list of results
!
!
• filter: Apply function to each element in a list and return only those for which the function returns true
var numbers:[Int] = [2,3,4] numbers.map({(x:Int) -> Int in return x * x}) // [4,9,16]
var numbers:[Int] = [2,3,4] let result = numbers.filter({return $0 % 2 == 0}) // [2,4]
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Higher Order Functions on Collections
• reduce: Use function to successively combine two elements in the list to calculate a combined result of the list
var numbers:[Int] = [2,3,4,5] numbers.reduce(0, +) // 14 numbers.reduce(1, *) // 120
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Example: Luhn’s Check1. Reverse the order of the digits in the number.
2. Take the first, third, ... and every other odd digit in the reversed digits and sum them to form the partial sum s1
3. Taking the second, fourth ... and every other even digit in the reversed digits:
1. Multiply each digit by two and sum the digits if the answer is greater than nine to form partial sums for the even digits
2. Sum the partial sums of the even digits to form s2
4. If s1 + s2 ends in zero then the original number is in the form of a valid credit card number as verified by the Luhn test.
Demo: Luhn’s Check
Swift Performance
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Perfomance: Measuring Errors
• Not using Optimized Code
• Not using equivalent code
• e.g. compare
• for (var i = 0; i < 10; i++)
• for i in 1..10
• Not making sure code isn’t completely removed by compiler
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
My Tests• Compared Swift with C and Objective-C (where
appropriate)
• Used [XCTTestCase measureBlock:]
• runs code several times and calculate average runtime
• iMac 2012 in iPhone 5s Simulator
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Example: Simple Loop
var result:UInt32 = 0 self.measureBlock() { var temp:UInt32 = 0 for (var i = 0; i <= HUNDRED_MILLION; i++) { temp ^= 12345678 } result = temp } println(result)
Swift__block u_int32_t result = 0; [self measureBlock:^{ u_int32_t temp = 0; for (int i = 0; i <= HUNDRED_MILLION; i++) { temp ^= 12345678; } result = temp; }]; NSLog(@"result: %d", result);
C
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Result: Simple Loop (100 Million Iterations)
Swift C
-Os/-O 0.059s 0.030s
-Ofast 0.011s 0.011s
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Result: Sum Up Elements of Array (100 Million Elements)
C Swift for-loop (i++)
Swift for-in-loop
Swift reduce(+)
Objective-C for-loop (i++)
Objective-C for-in-loop
-Os/-O 0.055s 1.712s 5.136s 4.961 2.418 1.210
-Ofast 0.028s 0.058s 0.156s 0.072s 2.459s 1.211s
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Performance: Conclusion• similar to Objective-C
• Lots of potential (see -Ofast results)
• Performance is likely going to improve in future betas
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
Swift still in Beta
• Performance
• Array semantics changed completely
• .. became ..<
• String Unicode handling is still work in progress
• Compiler often stumbles over somewhat more advanced Generics
CocoaHeads Köln, July 2014 Joachim Kurz, Mobile2b GmbH
References• The Swift Programming Language: https://itunes.apple.com/us/book/
the-swift-programming-language/id881256329?mt=11&ls=1
• Using Swift with Cocoa and Objective-C: https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11&ls=1
• http://stackoverflow.com/questions/24101718/swift-performance-sorting-arrays
• https://mobile.twitter.com/_dklein/status/490670315388039169
• https://www.mikeash.com/pyblog/friday-qa-2014-07-04-secrets-of-swifts-speed.html
• http://en.wikipedia.org/wiki/Generic_programming
• http://www.stlport.org/resources/StepanovUSA.html