Selector
如果方法名称在方法所在域是唯一的,可以只是用方法的名字来作为#selector的内容
let someMethod = #selector(callMe)
let anotherMethod = #selector(callMeWithParam)
let method = #selector(turn)
但如果再同一个作用域中存在同样名字的两个或多个方法 即使函数签名不同,也无法编译
@objc func commonFunc() {
}
@objc func commonFunc(input: Int) -> Int {
return input
}
let method = #selector(commonFunc) // 编译错误,`commonFunc` 有歧义
可以使用方法进行强制转换
let method1 = #selector(commonFunc as ()->())
let method2 = #selector(commonFunc as (Int)->Int)
实例方法的动态调用
class MyClass {
func method(number: Int) -> Int {
return number + 1
}
}
let f = MyClass.method
let object = MyClass()
let result = f(object)(1)
只适用于实例方法 对于属性的getter和setter是不能用类似的方法
class MyClass {
func method(number: Int) -> Int {
return number + 1
}
class func method(number: Int) -> Int {
return number
}
}
let f1 = MyClass.method
// class func method 的版本
let f2: (Int) -> Int = MyClass.method // 和 f1 相同
let f3: (MyClass) -> (Int) -> Int = MyClass.method // func method 的柯里化版
编译标记
// TODO: 未完成
// FIXME: 待修改
// MARK: 标记
@UIApplicationMain
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,
}
}
根据第三个参数初始化一个UIApplication或其子类的对象并开始接受事件(传入nil,意味使用默认的 UIApplication),最后一个参数指定了AppDelegate类作为应用的委托,被用来接受类似didFinishLaunching或者 didEnterBackground 这样的与应用生命周期相关的委托方法
虽然这个方法标明为返回一个int ,但是其实它并不会真正返回。它会一直存在于内存中,直到用户或者系统将其强制终止
在swift中 使用的是@UIApplicationMain
如果想使用自己的UIApplication 可以删除@UIApplicationMain 新建一个main.swift 特殊的文件
import UIKit
class MyApplication: UIApplication {
override func sendEvent(event: UIEvent!) {
super.sendEvent(event)
print("Event sent: \(event)"); }
}
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(MyApplication), NSStringFromClass(AppDelegate))
每次发送事件 (比如点击按钮)时,都可以监听到这个事件
@objc 和 dynamic
swift中继承于NSObject的class会自动为所有非private的类和成员加上@objc
可选协议和协议扩展
OC中的protocol里存在optional关键字,被这个关键字修饰的方法并非必须要被实现,但是,Swift中的protocol的所有方法必须都被实现
Swift中若想protocol中实现可选项,那么就需要在协议和方法前面加上@objc,同时要在方法前加optional修饰表示可以选择是否实现
对于protocol来说 如果想每个方法都是可选的,需要每个方法前面加optional
@objc protocol OptionalProtocol {
@objc optional func optionalMethod() // 可选
func necessaryMethod() // 必须
@objc optional func anotherOptionalMethod() // 可选
}
对于使用@objc修饰的protocol只能被class实现,Struct和Enum无法实现,无法令Struct和Enum所实现的协议中含有可选方法或者属性,同时,实现这个协议的class中的方法必须是@objc修饰 或者整个类继承自NSObject
protocol OptionalProtocol {
func optionalMethod() // 可选
func necessaryMethod() // 必须
func anotherOptionalMethod() // 可选
}
extension OptionalProtocol {
func optionalMethod() {
print("Implemented in extension")
}
func anotherOptionalMethod() {
print("Implemented in extension")
}
}
class MyClass: OptionalProtocol {
func necessaryMethod() {
print("Implemented in Class3")
}
func optionalMethod() {
print("Implemented in Class3")
}
}
let obj = MyClass()
obj.necessaryMethod() // Implemented in Class3
obj.optionalMethod() // Implemented inClass3
obj.anotherOptionalMethod() // Implemented in extension
内存管理,weak 和 unowned
unowned 设置以后即使它原来引用的内容已经被释放了,它仍然会保持对被已经释放了的对象的一个 "无效的" 引用,它不能是 Optional 值,也不会被指向 nil 。如果尝试调用这个引用的方法或者访问成员属性的话,程序就会崩溃。
因为weak引用的内容被释放之后,标记为weak的成员将会自动变为nil,所以,被weak修饰的变量尽量是optional值
建议
当能够确定在访问时不会被释放的话 尽量使用unowned
如果存在被释放的可能 就选择用weak
值类型和引用类型
Swift的类型分为值类型和引用类型
- 值类型
值类型被复制的时机是值类型的内容发生改变时
值类型在复制时,会将存储在其中的值类型一并进行复制,而对于其中的引用类型的话 则只复制一份引用 - 引用类型
1.在处理大量数据并且频繁操作(增删)其中元素时,选择NSMutableArray和NSMutableDictionary会更好
2.对于容器条目小而容器本身数目多的情况 选择Swift内建的Array和Dictionary
String 还是 NSString
1.Cocoa提供了足够多的操作String的方法
2.Swift中String是struct 通过配置常量赋值 在多线程编程时很重要.在不触及 NSString 特有操作和动态特性的时候,使用 String 的方法,在性能上也会有所提升
3.String实现了Collection协议 可以使用某些协议方法