欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swift Tips

程序员文章站 2022-07-02 19:20:20
...

Int和CPU架构有关

在32位CPU上(iphone5及以前)是Int32,64位上(5s及以后)为Int64。UInt同理。

可选链式调用

可选链式调用失败时,等号右侧的代码不会被执行

func createAddress() -> Address {
    print("Function was called.")
    return Address()
}
john.residence?.address = createAddress() // 不会输出打印

@autoclosure

autoclosure可以把表达式转化为闭包。

func judgeLog(@autoclosure predicate: () -> Bool, msg: String) {
    if predicate() {
        print(msg)
    }
}
judgeLog(2>1, msg: "2 > 1 is right")

assert & fatalError

assert是Debug时才起效,Release下不起效。而fatalError无论哪种情况都起效。可以按照需求来选择错误奔溃处理。

mutating

mutating修饰方法,用在struct,enum这些值类型中,他们的方法中修改属性必须使用mutating。

infix, prefix, postfix

在添加自定义操作符时,分别加上infix表示中位符 prefix前位符 postfix后位符。

infix operator +* {
    associativity none  //结合律,
    precedence 160      //优先级,乘除为150,加减为140
}
// 重载+*
func +* (left: Int, right: Int) -> Int {
    return (left * right + left + right)
}

inout

函数的参数默认是let,如果有时候需要修改传入的变量的值,需要添加inout关键字。

Designated & Convenientce & Required

designated初始化方法就是最普通的init方法。designated方法必须确保所有成员对象被初始化了。
初始化方法中依赖其他初始化方法,必须使用convenience。若父类实现了convenicence init那么子类可以直接使用父类这个方法来初始化。
required是强制子类必须重写的关键字。

初始化方法返回nil

init后加"?"或"!"允许在初始化中返回nil来实例化optional对象。

类型混合

let mixed1: [Any] = [1, "two", 3.0]
let mixed2 = [1, "two", 3.0] // [NSObject]
enum IntOrString {
    case IntValue(Int)
    case StringValue(String)
}
let mixed3 = [IntOrString.IntValue(1), IntOrString.StringValue("haha")]

dynamicType获取动态类型

protocol Copyable {
    func copy() -> Self
}
class MyClass: Copyable {
    var num: Int
    required init(num: Int) {
        self.num = num
    }
    func copy() -> Self {
        let result = self.dynamicType.init(num: self.num)
        return result
    }
}

多重optional

let aNil: String? = nil
let bNil: String?? = aNil
let cNil: String?? = nil   // bNil不等于cNil

lldb调试命令

运行时,lldb调试直接使用po指令可以打印对象的值 (po = print object)
使用bt可以打印出现场堆栈信息
使用fr v xxx打印桢信息,"fr v -R xxx"来打印多重变量信息

map方法

let arr = [1,2,3]
let doubled = arr.map({
    $0 * 2
})
print(doubled) // [2, 4, 6]

let num: Int? = 6
let result1 = num.map {
    $0 * 2
}
print(result1) // Optional(12)

where用法

let name = ["li ming", "wang hao", "xiao bai"]
name.forEach { (_name) in
    switch _name {
    case let x where x.hasPrefix("xiao"):
        print("[\(x)] is my family")
    default:
        print("[\(_name)] is not my family")
    }
}

let score: [Int?] = [99, 100, nil, 60]
score.forEach {
    if let s = $0 where s == 100 {
        print("you are so smart!")
    }
}

在拓展中也可以这么使用

extension Array where Element: Integer {
    // ...
}

类型方法

实例方法是被类型的某个实例调用的方法。你也可以定义类型本身调用的方法,这种方法就叫做类型方法。只需要在func前添加class。类型方法内部self指向这个类型本身,而不是类型的某个实例。

class MyClass {
    class func method() {}
}
MyClass.method()

实例方法的动态调用

class MyClass {
    func method(number: Int) -> Int {
        return number + 1
    }
}
let f = MyClass.method // 等价于let f = { (obj: MyClass) in obj.method }
let object = MyClass()
let result = f(object)(1) // 2

如果加入重载和类方法:

class MyClass {
    class func method(number: Int) -> Int { // #1
        return number
    }
    func method(number: Int) -> Int { // #2
        return number + 1
    }
    func method(numberA: Int, numberB: Int) -> Int { // #3
        return numberA + numberB
    }
}
let f0 = MyClass.method // 等价于类型方法 #1
let f1: Int -> Int = MyClass.method // 等价于f0
let f2: MyClass -> Int -> Int = MyClass.method // #2
let f3: MyClass -> (Int, Int) -> Int = MyClass.method // #3

let object = MyClass()
let result0 = f0(1)           // 1
let result1 = f1(1)           // 1
let result2 = f2(object)(1)   // 2
let result3 = f3(object)(2,2) // 4

条件编译

#if <condition>
    // ...
#elseif <condition>
    // ...
#else
    // ...
#endif

条件可以是os(OSX)/os(iOS),arch(x86_64)/arch(arm)/arch(arm64)/arch(i386)
也可以是自定义的一个条件变量:Build Settings->Swift Compiler->Custom Flags添加-D CONDITION_NAME

可选接口

// # 1 使用objective-c方式
@objc protocol OptionalProtocol {
    optional func optionalMethod()
    func necessaryMethod()
}
// # 2 使用接口拓展
protocol OptionalProtocol {
    func optionalMethod()
    func necessaryMethod()
}
extension OptionalProtocol {
    func optionalMethod() {}
}

求随机数

使用arc4random_uniform(arc4random在32位iPhone上有时程序奔溃)

// # 1
let maxValue: UInt32 = 10
print(Int(arc4random_uniform(maxValue)) + 1) 

// # 2
func randomInRange(range: Range<Int>) -> Int {
    let count = UInt32(range.endIndex - range.startIndex)
    return Int(arc4random_uniform(count)) + range.startIndex
}
for _ in 1...10 {
    print(randomInRange(1...10))
}

引用

100个Swift必备Tips
Swift教程