基础篇
1、static、const、extern 关键字
static:定义静态变量,声明局部变量时,编译时就为其分配内存,程序退出时才会释放。声明全局变量时,作用域只限于当前文件,其它类文件是访问不到的。
const:定义不可改变的常量值,相对于宏来讲,宏只是替换的,不会报编译错误,而 const会编译检查,会报编译错误。大量使用宏会造成编译缓慢,因为每次都需要替换,所以苹果推荐我们使用const常量。
extern:获取全局变量的值,不能用于定义变量。工作原理 - 先在当前文件需要全局变量,如果没有找到,才会到其它文件寻找。
使用场景
static与const的联合使用,声明一个静态的全局变量,例如可以替代宏,把一个经常使用的字符转常量,定义成一个全局的静态只读常量。
static NSString * const key = @"name";
extern与const联合使用,定义全局变量,FOUNDATION_EXTERN 是 extern 的宏定义。
.m文件
NSString * const KEYNAME = @"name";
.h文件
FOUNDATION_EXTERN NSString * const KEYNAME;
2、#import、#include、@class、import< >、import” “
- #import:防止重复编译,交叉引用。
- #include:重复编译头文件。
- @class:告诉编译器有这么一个类。
- import< >:导入的是系统的文件。
- import” “:导入的是自定义的文件。
3、@interface与@property
@interface 常用的三种:声明类(Class)、声明类别(Category)、声明扩展(Extension)。
声明类
@interface Dog : NSObject
@end
声明类别
@interface Dog(类别名)
@end
声明扩展
@interface Dog ()
@end
property 关键字自动生成某个成员变量的setter与getter方法
@property (nonatomic, strong) NSString *name;
自动生成
- (void)setName:(NSString *)name {
_name = name;
}
- (NSString *)name {
return _name;
}
4、属性关键字 strong、weak、assign、retain、copy、readwrite、readonly、automic、nonatomic
- automic:默认的,保证在多线程的情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题,一般用不到,因为会影响性能。
- nonatomic:非原子操作,不提供多线程保护,非线程同步,一般都用这个。
- assign:修饰基本的数据类型。
- strong:一般用于对象类型,保留新值,释放旧值,然后再将新值设置上去,主要用于修饰强引用的属性。
- weak:既不保留新值,也不释放旧值,在属性对象释放时,属性值也会清空,主要用于修饰弱引用的属性,一般用于代理、UI控件等。
- copy:用于希望获得原对象的副本而不改变原对象的内容(拷贝一个新的对象,原对象不变)。
- readwrite:可读可写,但需要手动实现setter与gette方法。
- readonly:只读,只生成getter方法。
5、self与super的区别
- self是调用自己的方法,而super是调用父类的方法。
- 使用self调用方法时会从当前类的方法列表中去寻找,若没有则会去父类中去寻找。而super则从父类中去寻找,调用父类的方法。
6、深拷贝与浅拷贝
- 浅拷贝只是复制了对象的指针,和原对象一样指向同一个地址。
- 深拷贝复制对象引用本身,指向的是一个新地址。
- 要想实现自定义对象的拷贝,必须实现NSCopying或是NSMutableCopying协议,实现该协议的copyWithZone方法和mutableCopyWithZone方法,深拷贝和浅拷贝的区别就在于copyWithZone方法的实现。
7、KVC与KVO
- KVC:键值编码 -> 通过指定的要访问属性的名字的字符串标识符,可以进行类的属性读取和设置。
- KVO:键值观察 -> 注册一个对象的观察者,当该对象的某个属性变化时能够接受到通知。
8、Notification与KVO的不同
- Notification:需要被观察者主动发出通知,然后观察者注册监听后再进行操作。
- KVO:被观察者不需要添加任何代码,所以谁监听谁注册,然后对响应事件进行处理。
9、对单例的理解
- 单例的生命周期和程序的生命周期相同,仅能生成一次且不能被销毁的唯一实例
- 一个特定的类中仅有一个实例对象
- 单例可以在程序的任何位置被访问
- 创建时使用静态变量保证单例对象始终存在
+ (Single *)shareInstance {
static Single *single = nil;
if (!single) {
single = [[Single alloc] init];
}
return single;
}
10、类目、延展、协议
类目(分类):指向已知的类,增加新的方法,不会破坏封装性。类目具有更高的优先级,如果跟原有的类冲突,将会覆盖原来的方法。
延展(类扩展):为一个类添加一些私有的成员变量和方法。
协议:声明一个方法,让别的类来实现,协议不是类,它是定义一个其他对象可以实现的接口。
11、tableView的重用机制
UITableView通过重用单元格的方式来达到节省内存的目的。通过为每个单元格指定一个重用标识符(reuseIdentifier),指定了单元格的种类。假如一个TableView有10个单元格,但是屏幕上最多只能显示4个,实际上系统只为其分配了4个单元格的内存,当滚动单元格时,屏幕内显示的单元格会重复使用这四个内存。简单理解就是单元格滑出屏幕时,就会将其放到一个重用池(数组)中,当要显示某一行单元格时,再将其取出来,如果没有,就直接创建。
12、程序的生命周期 (viewcontroller)类
- (void)loadView 加载视图,只调用一次。
- (void)viewDidLoad 视图加载完成,一般在这个方法中初始化用户界面,只调用一次
- (void)viewWillAppear:(BOOL)animated 视图将要显示,视图将要出现的时候调用。
- (void)viewDidAppear:(BOOL)animated 视图已经显示,视图出现的时候调用 。
- (void)viewWillDisappear:(BOOL)animated 视图将要消失,视图将要消失的时候调用。
- (void)viewDidDisappear:(BOOL)animated 视图已经消失,视图消失的时候调用
13、界面传值的几种方式
属性传值:一般从主页传到详情页。
init传值:需在详情页声明init方法。
Block传值:详情页传值到主页,block一般用于回调,传值需在详情页声明block类型,属性与传值方法。
协议传值(代理传值):在详情页声明协议,设置代理属性。
通知传值:多界面传值,适用于任意控制器。(NSNotificationCenter)。
单例传值:单例贯穿整个应用程序声明周期,利用单例传值适用于任何控制器,使用前提是在获取值的时候必须保证单例属性有值,否则获取值为nil。
内存篇
1、内存分配五大区
栈区:由编译器自动分配内存并释放
堆区:由开发者自己分配内存并释放
全局区(静态区):存储全局变量和静态变量
文字常量区:存放常量字符串,程序结束后由系统释放
代码区:存放函数体的二进制代码
2、对内存管理的理解
- OC中有三种内存管理方式:ARC(自动计数)、MRC(手动计数)、自动释放池。
- 当使用new、alloc、或是copy创建一个对象时,该对象引用计数器为1,如果不需要使用该对象时,可以向其发送release或autorelease消息,在使用完毕后进行销毁。如果retain了某个对象,需要release或autorelease该对象,保持retain和release方法的使用次数相等。
- 使用new、alloc、copy关键字生成的对象和retain了的对象需要手动释放,设置为autorelease的对象不需要手动释放,因为其会直接进入自动释放池。使用便利构造方法的对象也无需手动管理内存。
3、索引计数
创建一个对象后,索引计数就表示有多少个变量在使用这个对象,当索引计数为0时,就表示这个对象没人用了,就可以清除了,但有人使用,做了标记,却在不用的时候没有取消自己的索引计数,那么这块资源就永远被标记有人在用,无法释放,即内存泄漏。
4、ARC机制与其实现原理
- ARC就是在代码中自动加入retain/release,原先需要手动添加用来处理内存管理的引用计数的代码,可以自动的由编译器来执行。
- ARC并不是GC(垃圾回收机制),它只是一种代码静态分析工具,都是释放不需要的内存空间,不同的是ARC在编译的时候会自动加入retain/release,而GC是在运行的时候专门处理的工具,当引用计数为0时,就会释放空间。
5、内存管理的几条原则
- OC中内存管理机制中比较重要的一条规律是:谁申请,谁释放,要避免过早释放和内存泄漏。
- 当new、alloc、或copy方法创建一个对象时,该对象的引用计数为1,如果不适用该对象时,应向其发送release或者autorelease消息,在使用完毕后 进行销毁。
- 如果retain了某个对象,需要release或autorelease该对象,保持retain方法和release方法使用次数相等。
- 通过方法获取对象,该对象引用计数加一,需要在使用完毕后进行release。
6、ARC与非ARC的混合
- ARC项目引入非ARC文件,则标识 -fno-objc-arc
- 非ARC项目引入ARC文件,则标识 -fobjc-arc
待补充