2016年2月13日 星期六

Swift Class, Structure, Function

Some difference between classes and structs

ClassStructure
inheritanceO
passed by valueO
passed by referenceO
createclass CRectangle {
    var width = 200
}
struct SRectangle {
    var width = 200
}
constructvar cRet = CRectangle()
// class 不能直接用 CRectangle(width:300) 必需要定義一個 constructor
cRect.width // 為 200
var sRect = SRectangle(width:300)
sRect.width //  為 300
memoryvar cRect = CRectangle()
var cRect2 = cRect // copy reference

cRect2.width // 目前值是 200
cRect2.width = 500
cRect.width // cRect.width 也改變成了 500
var sRect = SRectangle()
var sRect2 = sRect // copy memory

sRect2.width // 目前值是 200
sRect2.width = 500
sRect.width // 不受 sRect2 影響還是 200
immutablelet cRect = CRectangle()
cRect.width = 500 
let sRect = SRectangle()
sRect.width = 500 // 會造成錯誤
mutating functionextension CRectangle {
    func changeWidth(width:Int){
        self.width = width
    }
}
extension SRectangle {
    mutating func changeWidth(width:Int){
        self.width = width
    }
}

Structures and Enumerations Are Value Types

A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.

You’ve actually been using value types extensively throughout the previous chapters. In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

Assignment and Copy Behavior for Strings, Arrays, and Dictionaries

In Swift, many basic data types such as String, Array, and Dictionary are implemented as structures. This means that data such as strings, arrays, and dictionaries are copied when they are assigned to a new constant or variable, or when they are passed to a function or method.

This behavior is different from Foundation: NSString, NSArray, and NSDictionary are implemented as classes, not structures. Strings, arrays, and dictionaries in Foundation are always assigned and passed around as a reference to an existing instance, rather than as a copy.

Constant and Variable Parameters

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake.

However, sometimes it is useful for a function to have a variable copy of a parameter’s value to work with. You can avoid defining a new variable yourself within the function by specifying one or more parameters as variable parameters instead. Variable parameters are available as variables rather than as constants, and give a new modifiable copy of the parameter’s value for your function to work with.

Define variable parameters by prefixing the parameter name with the var keyword:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func alignRight(var string: String, totalLength: Int, pad: Character) -> String {
    let amountToPad = totalLength - string.characters.count
    if amountToPad < 1 {
        return string
    }
    let padString = String(pad)
    for _ in 1...amountToPad {
        string = padString + string
    }
    return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, totalLength: 10, pad: "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"


In-Out Parameters

Variable parameters, as described above, can only be changed within the function itself. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func swapTwoInts(inout a: Int, inout _ b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"



reference:
http://iosdevelopersnote.blogspot.tw/2014/12/swift-struct-class.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID88
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID93
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID172
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID173

2016年2月12日 星期五

Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector

使用相同函式,不同方法,會造成error

error code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import UIKit

import UIKit

class ViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}


complier error:
1
Method 'performOperation' with Objective-C selector 'performOperation:' conflicts with previous declaration with the same Objective-C selector


解決函式重載問題


加入@nonobjc即可

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import UIKit

import UIKit

class ViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    @nonobjc
    func perform(operation: (Double, Double) -> Double) {
    }
}


Using Swift with Cocoa and Objective-C (Swift 2.1)





reference: