0.AOP
1.copy、mutableCopy
1 | // swift中的NSArray实现的copy与mutableCopy |
可见如果属性修饰用了copy, 如果属性上声明NSArray, 即便在赋值时使用NSMutableArray, 属性新值依然得到NSArray的实例,而容器的内存也会是新开辟的。
这就是常说的浅拷贝
而copy与mutableCopy的区别仅在于新创建的容器是可变与不可变
array的这个构造方法会进行深拷贝initWithArray:<#(nonnull NSArray *)#> copyItems:<#(BOOL)#>
1 | public convenience init(array: [Any], copyItems: Bool) { |
会申请内存空间,存储每个对象定义copy的返回对象。注意的是如果对象需要实现copy方法。cocoa自带的对象一般都有默认实现。
对于NSArray、NSDictionary应使用copy来保证它们的封装性
如果使用比如strong修饰,当NSMutableArray的实例赋给属性时,属性就变成了NSMutableArray,
由于strong修饰,属性指向了可变数组的内存区域,如果可变数组改变了,属性也会跟随改变反之亦然,
再有,此种情况运行时调用addObject:依然有效,因为isa已经不是NSArray了
block
为什么不能修改截获的自动变量的值
我们知道,block会把截获的自动变量设置成自身的属性
在block内部修改值,相当于设置了自身的属性,但是却无法改变原本的自动变量的值(全局变量,静态变量除外),这样就造成矛盾了。
也就是在oc代码中,明明在block中修改了自动变量的值,结果却没有改变!
所以有了__block修饰符来说明意图
经__block
修饰的变量会被编译套壳 __Block_byref
1 | struct __blockContext_block_impl_0 { |
在注释// by ref 可见意图,通过指针引用来间接修改值。
block属性只是自动变量的指针,在block内部通过属性找到自动变量的指针,进而改变值可以改变外部自动变量的值
1 | int alan |
关键是__forwarding
1 | // block修改自动变量的部分 |
1 | // block外部的自动变量的声明 |
1 | // 把自动变量赋给block |
在block内部想改变外部的自动变量时,获取到的是外部变量壳对象的引用
通过引用找到__forwarding
再找到真正的属性变量进行赋值
为什么不直接使用 alan->alan 即通过偏移直接赋值呢?
1 | // |
Block 的copy
swift 内存布局
swift如何实现多态