1.某个文件ARC和非ARC(MRC)的切换
设置为ARC:-fobjc-arc
设置为非ARC:-fno-objc-arc
2.MRC下的set方法
不等的话,先释放老的,再保留新的,再赋值。
copy和retain的set方法只有,只有在保留新对象的时候,一个使用copy,一个使用retain。
3.assign 和weak在修饰属性的时候的区别
a.它们所指的对象销毁以后,weak修饰的属性会置为nil,assign修饰的属性不置为nil。
b.assign可以修饰基本数据类型,weak只能修饰OC对象。
4.创建多线程的方法和在主线程执行。
a.NSThread,GCD的dispatch,子类化的NSOperation(加入NSOperationQueue)。
GCD 基于C语言的底层API,GCD主要与block结合使用,代码简洁高效。
NSOperation 属于Objective-C类,是基于GCD更高一层的封装。复杂任务一般用NSOperation实现。
b.performSelectorOnMainThread。
5.ViewController 的生命周期
按照执行顺序排列:
i. initWithCoder:通过nib文件初始化时触发。
ii. awakeFromNib:nib文件被加载的时候,会发生一个awakeFromNib的消息到nib文件中的每个对象。
iii. loadView:开始加载视图控制器自带的view。
iV. viewDidLoad:视图控制器的view被加载完成。
V. viewWillAppear:视图控制器的view将要显示在window上。
Vi. updateViewConstraints:视图控制器的view开始更新AutoLayout约束。
Vii. viewWillLayoutSubviews:视图控制器的view将要更新内容视图的位置。
Viii. viewDidLayoutSubviews:视图控制器的view已经更新视图的位置。
ViV. viewDidAppear:视图控制器的view已经展示到window上。
VV. viewWillDisappear:视图控制器的view将要从window上消失。
VVi. viewDidDisappear:视图控制器的view已经从window上消失。
6. OC的反射机制
i. class反射
通过类名的字符串形式实例化对象。
Class class = NSClassFromString(@"student");
Student *stu = [[class alloc] init];
将类名变为字符串。
Class class =[Student class];
NSString *className = NSStringFromClass(class);
ii. SEL的反射
通过方法的字符串形式实例化方法。
SEL selector = NSSelectorFromString(@"setName");
[stu performSelector:selector withObject:@"Mike"];
将方法变成字符串。
NSStringFromSelector(@selector*(setName:));
7.修改一个类的私有属性
i. 一种是通过KVC获取。
ii. 通过runtime访问并修改私有属性。
8.代码输出什么?
@implementation Son : Father
- (id)init {
if (self = [super init]) {
NSLog(@"%@", NSStringFromClass([self class])); // Son
NSLog(@"%@", NSStringFromClass([super class])); // Son
}
return self;
}
@end
// 解析:
self 是类的隐藏参数,指向当前调用方法的这个类的实例。
super是一个Magic Keyword,它本质是一个编译器标示符,和self是指向的同一个消息接收者。
不同的是:super会告诉编译器,调用class这个方法时,要去父类的方法,而不是本类里的。
上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前 Son *obj 这个对象。
9.block的注意点
i. 在block内部使用外部指针且会造成循环引用情况下,需要用__week修饰外部指针:
__weak typeof(self) weakSelf = self;
ii. 在block内部如果调用了延时函数还使用弱指针会取不到该指针,因为已经被销毁了,需要在block内部再将弱指针重新强引用一下。
__strong typeof(self) strongSelf = weakSelf;
iii. 如果需要在block内部改变外部栈区变量的话,需要在用__block修饰外部变量。
10.OS的沙盒目录结构是怎样的?
沙盒结构:
1). Application:存放程序源文件,上架前经过数字签名,上架后不可修改。
2). Documents:常用目录,iCloud备份目录,存放数据。(这里不能存缓存文件,否则上架不被通过)
3). Library:
Caches:存放体积大又不需要备份的数据。(常用的缓存路径)
Preference:设置目录,iCloud会备份设置信息。
4). tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能。
11.如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
// 使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
// 创建队列组
dispatch_group_t group = dispatch_group_create();
// 获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
/*加载图片1 */
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
/*加载图片2*/
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
/*加载图片3*/
dispatch_group_leave(group);
});
// 当并发队列组中的任务执行完毕后才会执行这里的代码
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
});
12.dispatch_barrier_async(栅栏函数)的作用是什么?
函数定义:dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
作用:
1.在它前面的任务执行结束后它才执行,它后面的任务要等它执行完成后才会开始执行。
2.避免数据竞争
// 1.创建并发队列
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
// 2.向队列中添加任务
dispatch_async(queue, ^{ // 1.2是并行的
NSLog(@"任务1, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务2, %@",[NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"任务 barrier, %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{ // 这两个是同时执行的
NSLog(@"任务3, %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务4, %@",[NSThread currentThread]);
});
// 输出结果: 任务1 任务2 ——》 任务 barrier ——》任务3 任务4
// 其中的任务1与任务2,任务3与任务4 由于是并行处理先后顺序不定。
13.Masonry里的UIView动画:
14.字体颜色渐变,大小渐变。