Objective-C 基础
NSString / NSArray 为什么用 copy 不用 strong
- @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作(就是把可变的赋值给不可变的),为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
- 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本。
- 如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。
- 总结:使用copy的目的是,防止把可变类型的对象赋值给不可变类型的对象时,可变类型对象的值发送变化会无意间篡改不可变类型对象原来的值。
OC 为什么是动态运行时语言
- 主要是将数据类型的确定由编译时,推迟到了运行时。简单来说, 运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
IBOutlet连出来的视图属性为什么可以被设置成weak
- 使用
storyboard创建的ViewController,那么会有一个叫_topLevelObjectsToKeepAliveFromStoryboard的私有数组强引用所有top level的对象,同时top level对象强引用所有子对象,那么vc没必要再强引用top level对象的子对象。
@property 的本质是什么?
- @property = ivar + getter + setter;
怎么使用 copy 关键字
NSString、NSArray、NSDictionary等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;block也经常使用copy关键字,具体原因见官方文档:Objects Use Properties to Keep Track of Blocks:- block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.
- 在 ARC 中写不写都行:
- 在 ARC 环境下,编译器会根据情況自动将栈上的 block 复制到堆上,比如以下情况:
block 作为函数返回值时
将 block 赋值给 __strong 指针时(property 的 copy 属性对应的是这一条)
block 作为 Cocoa API 中方法名含有 using Block 的方法参数时
block 作为 GCD API 的方法参数时
其中, block 的 property 设置为 copy, 对应的是这一条:将 block 赋值给 __strong 指针时。
换句话说:
对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。你也许会感觉我这种做法有些怪异,不需要写还依然写。如果你这样想,其实是你“日用而不知”,你平时开发中是经常在用我说的这种做法的,比如下面的属性不写copy也行,但是你会选择写还是不写呢?