iOS 面试之道 阅读笔记(1)

数据结构

Array

关于Swift的数组,有三种不同的形式:

  • ContiguousArray: 其实我之前也一直没有注意这个形式的数组,因为平时更多在写ObjC,很少写Swift。ContiguousArray就是强制规划一个连续的空间来储存Elements。当用ContiguousArray来储存对象数据(class或@objc)时,其性能优于Array。
  • Array: 当Array储存值类型的数据的时候,内存空间是连续的。但是当储存类型是对象(class或@objc)的时候,Array会自动桥接到NSArray上,内存可能不连续。其实可以看出,当Array和ContiguousArray都储存值类型(struct或enumeration)的话,他们的性能相当。
  • ArraySlice: 数组片段,它的作用就是让我们更快和更高效地对一个大数组的其中一部分最处理。ArraySlice是不会创建新的存储空间的,它和原本的Array在内存上共享同一区域。但是,这并不意味修改ArraySlice中的元素会影响到原来的Array。

ContiguousArray的创建:

var cArray = ContiguousArray<Any>(repeating: 0, count: 3)
print(type(of: cArray))  // "ContiguousArray<Any>\n"

Array的count和capacity:

我们知道,当Array中的元素增加的时候,如果数组的内存不足,就需要新建一个更大的数组,然后从旧的数组中复制所有元素到新的数组里。现在的高级语言的Array都是Dynamic Array,你不需要自己去给数组扩容。为了提高数组扩的容的效率,底层代码都是成倍数的增加数组的大小。如Swift的Array的增长因子是2(阅读:https://blog.csdn.net/honglicu123/article/details/77541943)。所以Capacity和Count是不同的,Capacity是指这个数组的总大小,Count是现在所有存在元素的个数。例子:

var cArray = ContiguousArray<Any>(repeating: 0, count: 3)
print(cArray.count)        // 3
print(cArray.capacity)     // 3

cArray.append(9)
print(cArray.count)        // 4
print(cArray.capacity)     // 6

// 当removeAll的时候,数组的所有空间都会被释放掉
cArray.removeAll()        
print(cArray.count)        // 0
print(cArray.capacity)     // 0

Array的reserveCapacity(_:):

正如上面所说,当数组扩容的时候是有性能损耗的。当你大概知道需要多大内存容量的数组的时候,就可以用reserveCapacity(_:)来创建和保持数组的大小,省去数组Capacity变化带来的性能损耗。

ArraySlice的index并不总是开始于0:

ArraySlice会保留在原本数组中相同元素的index。

let absences = [0, 2, 0, 4, 0, 3, 1, 0]

let midpoint = absences.count / 2
//
let firstHalf = absences[..<midpoint]
let secondHalf = absences[midpoint...]

firstHalf[0]    // 0
secondHalf[0]   // Fatal error: Index out of bounds

ArraySlice会持有一个对原数组的强应用:

这意味着可能存在的内存溢出。在Swift文档中有如下建议:

Important: Long-term storage of ArraySlice instances is discouraged. A slice holds a reference to the entire storage of a larger array, not just to the portion it presents, even after the original array's lifetime ends. Long-term storage of a slice may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory and object leakage.

当对ArraySlice做修改的时候,会影响到原数组吗:
虽然在前面说到,ArraySlice会持有一个对原数组的强应用,且ArraySlice是原数组中一个片段的映射(不知道映射这个解释合不合适),也就是ArraySlice共享了原数组片段的内存地址。但是,答案是不会的。这是因为Swift做好了Copy-on-write,ArraySlice和原Array中,任何一个有改变,都会copy一个备份做改变。

Set and Dictionary

Set和Dictionary在查找上都是O(1),这是源于他们都采用了hash。他们在存储时都是无序的。如果你有需求将一个自定义的类放入Set中或作为Dictionary的Key,那么这个类需要满足Hashable Protocal。

Dictionary的value可以为nil吗:

可以的。当你在创建一个dictionary的时候,如果value为nil,则这个字典中所有的value都会转化为optional。

另外,我们知道在Swift中去删除一个Key-Value pair,我们只需要给这个key所对应的value赋值nil。那么当value为nil时,这个方法会不会失效?答案是不会。

最后,当一个value是nil的时候,用if let判断时会怎样?答案是if let会通过,value为nil。例子:

var dic = ["a": 1,
           "b": nil,
           "c": 3]

var dicA = ["a": 1,
            "b": 2,
            "c": 3]
            
print(dic)     // ["b": nil, "a": Optional(1), "c": Optional(3)]
print(dicA)    // ["b": 2, "a": 1, "c": 3]

// if let
if let valueFromB = dic["b"] {
    print("b has value: \(valueFromB)")
} else {
    print("b has no value")
}

// 输出: b has value: nil

// 删除b
dic["b"] = nil
print(dic)     // ["a": Optional(1), "c": Optional(3)]

String

对比与Objective-C,swift把很多类都变成了struct,字符串也不例外。这样的好处是增加了代码的安全,因为Swift为你做好了Copy-on-write,你也不用再像写ObjC那样要特别留意用copy关键字和动不动就要copy一下。当然,通过用inout关键字也是能实现传递引用的。

获得所有字符:
用一个Array来获得一个所有字符的数组。

let string = "abc"        // "abc"
let chars = Array(string) // ["a", "b", "c"]

subString:
String和Array很像,当你计算出一个range后,你就可以获得子字符串。

let fqdn = "useyourloaf.com"
let tldEndIndex = fqdn.endIndex
let tldStartIndex = fqdn.index(tldEndIndex, offsetBy: -3)
let range = Range(uncheckedBounds: (lower: tldStartIndex, upper: tldEndIndex))
fqdn[range]    // "com"

“From https://useyourloaf.com/blog/swift-string-cheat-sheet/”

Reference:
https://xiaozhuanlan.com/ios-interview 故胤道长和唐巧两位大神的书《iOS 面试之道》
https://useyourloaf.com
https://swiftdoc.org/

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

推荐阅读更多精彩内容