1、Frame和Bounds的区别?
image.png
(图片摘抄网络,侵权删)
- frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
- bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)
bounds有这么一个特点:
它是参考自己坐标系,它可以修改自己坐标系的原点位置,进而影响到“子view”的显示位置。
推荐一个网址(非常详细):https://blog.csdn.net/chy555chy/article/details/51776716
2、列出常见的保证线程安全的方式
@synchronized、NSLock、dispatch_semaphore、NSCondition、pthread_mutex、OOSpinLock等
3、block的几种类型和存储位置
image.pngvoid (^block)(void) = ^{
NSLog(@"block");
};
block();
NSLog(@"%@",block);//NSGlobalBlock
//== ====>copy 栈===>堆 ref
int a = 10;
void (^block1)(void) = ^{
NSLog(@"%d",a);
NSLog(@"block");
};
NSLog(@"%@",block1);//NSMallocBlock
NSLog(@"%@",^{
NSLog(@"%d",a); //NSStackBlock
});
4、什么时候会使用Core Graphics,是线程安全的吗?
绘图(不是很了解,求大神解答)
5、你会如何存储用户的一些敏感信息,如登录的token
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。
6、GCD的几种队列类型,并简要描述
// 四种队列
//1、主队列(是串行队列)
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//2、全局并行队列
dispatch_queue_t concu = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//两个参数,前者是优先级,后者目前用不到
//3、创建串行队列
dispatch_queue_t queueSerial = dispatch_queue_create("je", DISPATCH_QUEUE_SERIAL);//两个参数,前者是名字(注意是c字符串),后者是队列类型。
//4、创建并行队列(一般使用系统带的全局并行队列即可)
dispatch_queue_t queueConcu = dispatch_queue_create("jr2", DISPATCH_QUEUE_CONCURRENT);
7、下面代码在什么条件下,会输出什么?
//TestViewController
@implementation TestViewController
- (void)testMethod {
NSLog(@"TestViewController");
}
//TestViewController+Category1
@implementation TestViewController (Category1)
- (void)testMethod {
NSLog(@"TestViewController+Category1");
}
//TestViewController+Category2
@implementation TestViewController (Category2)
- (void)testMethod {
NSLog(@"TestViewController+Category2");
}
//调用
TestViewController *vc = [TestViewController new];
[vc testMethod];
答:输出TestViewController+Category2(往往是最后一个创建的)
8、简述一个Runloop循环流程,即内部的逻辑
1、通知Observer:即将进入loop
2、通知Observer:将要处理Timer
3、通知Observer:将要处理Source0(注:事件源在这里笔者按函数调用栈来分的,分为Source0(用户主动触发的,非基于端口port的)、Source1(基于端口port的))
4、处理Source0(关于Source1我们可以这样理解:该事件是基于端口的事件,所以会进行内部的分发出timer事件与Source0事件)
5、如果有Source1就跳到第9步(在这里我们可以看到runloop的执行循环,只有把timer与事件源全部处理完才会进入休眠,否则会循环执行直到处理完为止)
6、通知Observer:线程即将休眠
7、休眠,等待唤醒
8、通知Observer:线程刚被唤醒
9、处理唤醒时收到的消息,之后跳回第2步
10、通知Observer:即将退出loop(当runloop的时间到了或者当所在线程挂掉都会退出)
大神文章:https://blog.csdn.net/lifufa/article/details/50722961
9、说说你遇到过的技术难点和解决思路?(开放题)
网友评论