1. class 和 struct 的區(qū)別
class 為類, struct 為結(jié)構(gòu)體, 類是引用類型, 結(jié)構(gòu)體為值類型, 結(jié)構(gòu)體不可以繼承
2.map悲柱、filter、reduce 的作用
map 用于映射, 可以將一個列表轉(zhuǎn)換為另一個列表
[1, 2, 3].map{"\($0)"}// 數(shù)字數(shù)組轉(zhuǎn)換為字符串數(shù)組
//["1", "2", "3"]
filter 用于過濾, 可以篩選出想要的元素
[1, 2, 3].filter{$0 % 2 == 0} // 篩選偶數(shù)
//[2]
reduce 合并
[1, 2, 3].reduce(""){$0 + "\($1)"}// 轉(zhuǎn)換為字符串并拼接
//"123"
3.map 與 flatmap 的區(qū)別
flatmap 有兩個實現(xiàn)函數(shù)實現(xiàn)
public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
這個方法, 中間的函數(shù)返回值為一個可選值, 而 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]
另一個實現(xiàn)
public func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element] where SegmentOfResult : Sequence
中間的函數(shù), 返回值為一個數(shù)組, 而這個 flapmap 返回的對象則是一個與自己元素類型相同的數(shù)組
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]
其實這個實現(xiàn), 相當于是在使用 map 之后, 再將各個數(shù)組拼起來一樣的
[[1], [2, 3], [4, 5, 6]].map(someFunc).reduce([Int]()) {$0 + $1}
// [1, 2, 3, 4, 5, 6]
4.如何獲取當前代碼的函數(shù)名和行號
file 用于獲取當前文件文件名
line 用于獲取當前行號
column 用于獲取當前列編號
function 用于獲取當前函數(shù)名
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 五種訪問控制的權(quán)限
//1.當private 或fileprivate 修飾屬性的時候
privte 修飾的屬性只能在本類的作用域且在當前文件內(nèi)能訪問
fileprivate 修飾的屬性只能在當前文件內(nèi)訪問到,不管是否在本類作用域
//2. fileprivate 修飾方法的時候
fileprivate 修飾的方法廷粒,類的外部無法調(diào)用
fileprivate 修飾方法窘拯,子類定義的同一個文件中红且,可以訪問
fileprivate 修飾方法坝茎,子類定義不在同一個文件,不可以訪問
//3.public 和 open 的區(qū)別
這兩個都用于在模塊中聲明需要對外界暴露的函數(shù), 區(qū)別在于, public 修飾的類, 在模塊外無法繼承, 而 open 則可以任意繼承, 公開度來說, public < open
6. guard 的使用場景
swift 的語法糖之一
//當(條件) 為false 的時候進入{}
guard 條件
{
}
7.if let 語法糖使用場景
swift 中因為有optional暇番,所以需要經(jīng)常判空嗤放,舉例說明if let 解決了什么問題
//不使用if let
func doSometing(str: String?){
...
}
let value :String ! = str
if value != ni {
//如果value 不為 nil進入大括號執(zhí)行
}
//使用了if let 簡潔了很多
func doSometing(str: String?){
...
}
if let value = str {
//如果value 不為 nil進入大括號執(zhí)行
}
8.defer的使用場景
defer 語句塊中的代碼, 會在當前作用域結(jié)束前調(diào)用, 常用場景如異常退出后, 關(guān)閉數(shù)據(jù)庫連接
func someQuery() -> ([Result], [Result]){
//假如打開數(shù)據(jù)庫失敗
let db = DBOpen("xxx")
defer {
db.close()
}
//或者 查詢失敗導致異常退出 調(diào)用defer,執(zhí)行里面的代碼
guard results1 = db.query("query1") else {
return nil
}
guard results2 = db.query("query2") else {
return nil
}
return (results1, results2)
}
9.String 與 NSString 的關(guān)系與區(qū)別
NSString 與 String 之間可以隨意轉(zhuǎn)換
let someString = "123"
let someNSString = NSString(string: "n123")
let strintToNSString = someString as NSString
let nsstringToString = someNSString as String
10.associatedtype 的作用
簡單來說就是 protocol 使用的泛型
例如定義一個列表協(xié)議
protocol ListProtcol {
associatedtype Element
func push(_ element:Element)
func pop(_ element:Element) -> Element?
}
實現(xiàn)協(xié)議的時候, 可以使用 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.關(guān)于泛型的使用
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 中的懶加載壁酬,只有被調(diào)用到的時候次酌,才初始化和賦值
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循環(huán)引用解決
在其參數(shù)前面使用[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 是一個靜態(tài)語言, 所以沒有 Objective-C 中的消息發(fā)送這些動態(tài)機制, dynamic 的作用就是讓 swift 代碼也能有 Objective-C 中的動態(tài)機制, 常用的地方就是 KVO 了, 如果要監(jiān)控一個屬性, 則必須要標記為 dynamic, 可以參考文章http://www.reibang.com/p/ae26100b9edf
什么時候使用 @objc
@objc 用途是為了在 Objective-C 和 Swift 混編的時候, 能夠正常調(diào)用 Swift 代碼. 可以用于修飾類, 協(xié)議, 方法, 屬性.
常用的地方是在定義 delegate 協(xié)議中, 會將協(xié)議中的部分方法聲明為可選方法, 需要用到@objc
@objc protocol OptionalProtocol {
@objc optional func optionalFunc()
func normalFunc()
}
class OptionProtocolClass: OptionalProtocol {
func normalFunc() {
}
}
let someOptionalDelegate: OptionalProtocol = OptionProtocolClass()
someOptionalDelegate.optionalFunc?()
17. 什么是高階函數(shù)
一個函數(shù)如果可以以某一個函數(shù)作為參數(shù), 或者是返回值, 那么這個函數(shù)就稱之為高階函數(shù), 如 map, reduce, filter
18. static 和 class 有什么區(qū)別
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)
浮點數(shù)(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
}
}
//枚舉關(guān)聯(lián)值
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; 會導致死循環(huán)
//return self.command; 會導致死循環(huán)
//return _command; 會導致死循環(huán)
//且不能像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 不會調(diào)用璃搜,只有在初始化上下文之外,屬性發(fā)生改變的時候調(diào)用鳞上;
給屬性添加觀察者屬性的時候这吻,必須聲明屬性類型,否則編譯會報錯篙议;
var command :Int {
willSet {
print("newValue is \(newValue)")
}
didSet {
print("newValue is \(newValue)")
print("oldValue is \(oldValue)")
}
}