iOS 日常小知识点总结
define和const常量有什么区别
define在预处理阶段进行替换, const常量在编译阶段使用;
宏不做类型检测,仅仅进行替换, const常量有数据类型,会执行类型检测;
define不能调试,const常量可以调试;
define定义的常量在替换后运行过程中会不断的占用内存, 而const定义的常量存储在数据段只有一分copy,效率更高
define可以进行定义一些简单的函数, const不可以;
atomic一定是线程安全吗? nonatomic一定线程不安全吗?
这个问题, 看怎么理解, atomic修饰的属性, 保证它的setter和getter方法一定是线程安全, 但是这个属性的相关操作不是线程安全的;其本质是在getter和setter中添加@synchronized()保证安全;
nonatomic则一定是不安全的;
例子:一个atomic修饰的NSMutableArray *muArr; 则muArr的getter和setter一定是线程安全的, 但是对这个数组的相关操作例如[muArr addObject]之类的都不是线程安全的;atomic能保证getter时取到一个完整点值;
结构体和类的区别:
| 结构体 | 类 |
|---|---|
| 只能封装属性 | 能封装属性和方法 |
| 分配在栈区,空间小,但是效率高;如果在结构体中赋值很多属性,会降低程序运行的效率 | 分配在堆区,空间较大但是读取效率低 |
| 结构体直接赋值 | 赋值的是对象的指针 |
@dynamic和@synthesize比较
@dynamic关键字: 表示必须要自己实现getter和setter方法;
@synthesize关键字: 表示系统会自动生成getter和setter方法, 如果自己实现了就会替换掉系统的;
NSCache 对NSDictionary的优点:
-
NSCache采用LRU规则, 会对超出限制的数据进行清除; -
NSCache会在系统内存很低时自动释放一些对象; -
NSCache是线程安全的;不需要对cache加锁; -
NSCache的key只是做强引用, 不需要实现NSCoping协议;
编译和链接的过程:
像C++, OC都是编译类型语言,在执行时需要先通过编译器生成机器码,机器码可以直接在CPU上执行,所以效率比较高;
像Python, JS都是直译式语言, 不需要经过编译的过程, 而是在执行的时候通过一个中间的解释器将代码解释为CPU可以执行的代码;所以直译型语言的效率低一些, 但是编写效率高;
以下以OC为例:
1.编译器前端的任务:语法分析, 语义分析, 生成中间代码, 在这个过程中会进行类型检查, 如果发现错误和警告会标注出哪行;
2.编译器后端的任务:进行机器无关的代码优化, 生成机器语言, 并进行机器相关的代码优化;
以打印一行”hello world”为例需要四个步骤:预处理, 编译, 汇编, 链接;
去掉导航条下方的线
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];
@property的本质:
在编译阶段由编译器自动帮我们生成ivar成员变量,getter方法, setter方法
@property = ivar + getter + setter; “属性” (property)有两大概念:ivar(实例变量)、getter+setter(存取方法)
“属性” (property)作为 Objective-C 的一项特性,主要的作用就在于封装对象中的数据。
Objective-C 对象通常会把其所需要的数据保存为各种实例变量。
实例变量一般通过“存取方法”(access method)来访问。
其中,“获取方法” (getter)用于读取变量值,而“设置方法” (setter)用于写入变量值。