swift 小知识点汇总

1. class 和 struct 的区别

class 为类, struct 为结构体, 类是引用类型, 结构体为值类型, 结构体不可以继承

2.map、filter、reduce 的作用

map 用于映射, 可以将一个列表转换为另一个列表

[1, 2, 3].map{"\($0)"}// 数字数组转换为字符串数组
//["1", "2", "3"]

filter 用于过滤, 可以筛选出想要的元素

[1, 2, 3].filter{$0 % 2 == 0} // 筛选偶数
//[2]

reduce 合并

[1, 2, 3].reduce(""){$0 + "\($1)"}// 转换为字符串并拼接
//"123"

3.map 与 flatmap 的区别

flatmap 有两个实现函数实现

    public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] 

这个方法, 中间的函数返回值为一个可选值, 而 flatmap 会丢掉那些返回值为 nil 的值
例如

//例如
["1", "@", "2", "3", "a"].flatMap{Int($0)}
// [1, 2, 3]
["1", "@", "2", "3", "a"].map{Int($0) ?? -1}
//[Optional(1), nil, Optional(2), Optional(3), nil]

另一个实现
public func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element] where SegmentOfResult : Sequence
中间的函数, 返回值为一个数组, 而这个 flapmap 返回的对象则是一个与自己元素类型相同的数组

func someFunc(_ array:[Int]) -> [Int] {
    return array
}
[[1], [2, 3], [4, 5, 6]].map(someFunc)
//[[1], [2, 3], [4, 5, 6]]
[[1], [2, 3], [4, 5, 6]].flatMap(someFunc)
//[1, 2, 3, 4, 5, 6]

其实这个实现, 相当于是在使用 map 之后, 再将各个数组拼起来一样的

[[1], [2, 3], [4, 5, 6]].map(someFunc).reduce([Int]()) {$0 + $1}
// [1, 2, 3, 4, 5, 6]

4.如何获取当前代码的函数名和行号

file 用于获取当前文件文件名

line 用于获取当前行号

column 用于获取当前列编号

function 用于获取当前函数名

var file: String = #file
var line: String = #line
var column: String = #column
var function: String = #function
method: String = #function,
print("\(file)--\(line)--\(columne)--\(function))

5.private,fileprivate,internal,public 和 open 五种访问控制的权限

//1.当private 或fileprivate 修饰属性的时候
privte 修饰的属性只能在本类的作用域且在当前文件内能访问
fileprivate 修饰的属性只能在当前文件内访问到,不管是否在本类作用域

//2. fileprivate 修饰方法的时候
fileprivate 修饰的方法,类的外部无法调用
fileprivate 修饰方法,子类定义的同一个文件中,可以访问
fileprivate 修饰方法,子类定义不在同一个文件,不可以访问


//3.public 和 open 的区别
这两个都用于在模块中声明需要对外界暴露的函数, 区别在于, public 修饰的类, 在模块外无法继承, 而 open 则可以任意继承, 公开度来说, public < open

6. guard 的使用场景

swift 的语法糖之一

//当(条件) 为false 的时候进入{}
guard 条件
{
        
}

7.if let 语法糖使用场景

swift 中因为有optional,所以需要经常判空,举例说明if let 解决了什么问题

//不使用if let
func doSometing(str: String?){
    ...
}
let value :String ! = str
if value != ni {
     //如果value 不为 nil进入大括号执行
}

//使用了if let 简洁了很多
func doSometing(str: String?){
     ...
}
if let value = str {
    //如果value 不为 nil进入大括号执行
}

8.defer的使用场景

defer 语句块中的代码, 会在当前作用域结束前调用, 常用场景如异常退出后, 关闭数据库连接

func someQuery() -> ([Result], [Result]){
    //假如打开数据库失败        
    let db = DBOpen("xxx")
    defer {
        db.close()
    }
    //或者 查询失败导致异常退出 调用defer,执行里面的代码
    guard results1 = db.query("query1") else {
        return nil
    }
    guard results2 = db.query("query2") else {
        return nil
    }
    return (results1, results2)
}

9.String 与 NSString 的关系与区别

NSString 与 String 之间可以随意转换

let someString = "123"
let someNSString = NSString(string: "n123")
let strintToNSString = someString as NSString
let nsstringToString = someNSString as String

10.associatedtype 的作用

简单来说就是 protocol 使用的泛型
例如定义一个列表协议

protocol ListProtcol {
    associatedtype Element
    func push(_ element:Element)
    func pop(_ element:Element) -> Element?
}

实现协议的时候, 可以使用 typealias 指定为特定的类型, 也可以自动推断, 如

class IntList: ListProtcol {
    typealias Element = Int // 使用 typealias 指定为 Int
    var list = [Element]()
    func push(_ element: Element) {
        self.list.append(element)
    }
    func pop(_ element: Element) -> Element? {
        return self.list.popLast()
    }
}
class DoubleList: ListProtcol {
    var list = [Double]()
    func push(_ element: Double) {// 自动推断
        self.list.append(element)
    }
    func pop(_ element: Double) -> Double? {
        return self.list.popLast()
    }
}

11.关于泛型的使用

class AnyList<T>: ListProtcol {
    var list = [T]()
    func push(_ element: T) {
        self.list.append(element)
    }
    func pop(_ element: T) -> T? {
        return self.list.popLast()
    }
}

12.可以使用 where 字句限定 Element 类型, 如:

extension ListProtcol where Element == Int {
    func isInt() ->Bool {
        return true
    }
}

13. ?? 的用法

可选值的默认值, 当可选值为nil 的时候, 会返回后面的值. 如

let someValue = optional1 ?? 0

14. lazy 的用法

swift 中的懒加载,只有被调用到的时候,才初始化和赋值

class LazyClass {
    lazy var someLazyValue: Int = {
        print("lazy init value")
        return 1
    }()
    var someNormalValue: Int = {
        print("normal init value")
        return 2
    }()
}
let lazyInstance = LazyClass()
print(lazyInstance.someNormalValue)
print(lazyInstance.someLazyValue)

15.swift block循环引用解决

在其参数前面使用[weak self]或者[unowned self]

let emtyOb = Observable<String>.empty()
_ = emtyOb.subscribe(onNext: { [weak self] (number) in
    
    print("订阅:",number)
    self.label.text = number
})

16. dynamic 的用法

由于 swift 是一个静态语言, 所以没有 Objective-C 中的消息发送这些动态机制, dynamic 的作用就是让 swift 代码也能有 Objective-C 中的动态机制, 常用的地方就是 KVO 了, 如果要监控一个属性, 则必须要标记为 dynamic, 可以参考文章http://www.jianshu.com/p/ae26100b9edf

什么时候使用 @objc
@objc 用途是为了在 Objective-C 和 Swift 混编的时候, 能够正常调用 Swift 代码. 可以用于修饰类, 协议, 方法, 属性.
常用的地方是在定义 delegate 协议中, 会将协议中的部分方法声明为可选方法, 需要用到@objc

@objc protocol OptionalProtocol {
    @objc optional func optionalFunc()
    func normalFunc()
}
class OptionProtocolClass: OptionalProtocol {
    func normalFunc() {
    }
}
let someOptionalDelegate: OptionalProtocol = OptionProtocolClass()
someOptionalDelegate.optionalFunc?()

17. 什么是高阶函数

一个函数如果可以以某一个函数作为参数, 或者是返回值, 那么这个函数就称之为高阶函数, 如 map, reduce, filter

18. static 和 class 有什么区别

static 定义的方法不可以被子类继承, class 则可以

class AnotherClass {
    static func staticMethod(){}
    class func classMethod(){}
}
class ChildOfAnotherClass: AnotherClass {
    override class func classMethod(){}
    //override static func staticMethod(){}// error
}

19.枚举定义

与OC不一样,Swift的枚举扩展性很强了,OC只能玩Int,swift 支持

整型(Integer)
浮点数(Float Point)
字符串(String)
布尔类型(Boolean)

enum Movement {
    case letf
    case right
    case top
    case bottom
}
enum Area: String {
    case Dong = "dong"
    case Nan = "nan"
    case Xi = "xi"
    case Bei = "bei"
}

//嵌套枚举
enum Area {
    enum DongGuan {
        case NanCheng
        case DongCheng
    }
    
    enum GuangZhou {
        case TianHe
        case CheBei
    }
}

//枚举关联值
enum Trade {
    case Buy(stock:String,amount:Int)
    case Sell(stock:String,amount:Int)
}

let trade = Trade.Buy(stock: "003100", amount: 100)

switch trade {
case .Buy(let stock,let amount):
    
    print("stock:\(stock),amount:\(amount)")
    
case .Sell(let stock,let amount):
    print("stock:\(stock),amount:\(amount)")
default:
    ()
}

20. swift中set 、get 方法

swift 中的set 和 get 要复杂一点。 在swift 中主要分存储型属性计算型属性 这两种 , 一般 我们只是给计算属性添加 get\set 重写

var command:Int {
    get {
        //return command; 会导致死循环
        //return self.command; 会导致死循环
        //return _command; 会导致死循环
        //且不能像OC那样 return _command;
        return 1
    }
    set {
        //新值 newValue
        //value 为一个外部属性变量
        value = newValue
    }
}

//为了解决储型属性的set、get 方法问题
var _command:int?
var command :Int {
    get {
       return _command 
    }
    set {
       _command = newValue 
    }
}

21. swift 中 willset 和didset 方法

属性初始化的时候,willSet 和didSet 不会调用,只有在初始化上下文之外,属性发生改变的时候调用;
给属性添加观察者属性的时候,必须声明属性类型,否则编译会报错;

var command :Int {
    willSet {
       print("newValue is \(newValue)")
    }
    didSet {
      print("newValue is \(newValue)")
      print("oldValue is \(oldValue)")
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容