iOS小知识

358 阅读4分钟

1.某个文件ARC和非ARC(MRC)的切换



设置为非ARC

设置为ARC:-fobjc-arc

设置为非ARC:-fno-objc-arc

2.MRC下的set方法

不等的话,先释放老的,再保留新的,再赋值。

copy和retain的set方法只有,只有在保留新对象的时候,一个使用copy,一个使用retain。


copy的set方法


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.字体颜色渐变,大小渐变。