iOS笔试题收集

GCD -Grand Central Dispatch

GCD包含于libdispatch.dylib,系统默认加载这个库
GCD 是纯C语言的,函数大多以dispatch开头。

任务和队列

任务

既是要执行什么任务。

队列

既是存放任务的。

定制任务

确定想做的事情

将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行
提示:任务的取出遵循队列的FIFO原则:先进先出,后进后出

执行任务

GCD中有2个用来执行任务的函数:

同步方式:dispatch_sync(dispatch_quene_t queue,dispatch_block_t block)

异步方式:dispatch_async(dispatch_queue_t queue,dispatch_block_t block)

把block中的任务提交给queue队列来执行


同步(dispatch_sync)和异步(dispatch_async)的区别

同步:在当前线程中执行

异步:在另一条线程中执行

队列

队列的类型

GCD的队列可以分为2大类型:并发队列(Concurrent Dispatch Queue)和串行队列(Serial Dispatch Queue

并发队列(Concurrent Dispatch Queue)

可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务),并发功能只有在异步函数(dispatch_async(dispatch_queue_t queue_t,dispatch_block_t block))中才有效。

串行队列(Serial Dispatch Queue)

让任务一个接着一个执行(一个任务执行完毕后,再执行下一个任务)

Tips:容易混淆的几个概念-同步、异步、并发、串行

同步和异步决定要不要开启新的线程

同步:在当前线程中执行任务,不具备开启新线程的能力

异步:在新的线程中执行任务,具备开启新线程的能力

并发和串行决定了任务的执行方式

并发:多个任务并发(同时)执行

串行:一个任务执行完毕后,再执行下一个任务

串行队列

使用dispatch_queue_create函数创建串行队列
函数原型:
dispatch_queue_t dispatch_queue_create(const char *label,dispatch_queue_attr_t attr)

label:队列名称-C语言的字符串、attr:队列属性-一般用NULL即可

示例:dispatch_queue_t queue = dispatch_queue_create("com.jiakaotuan.Gcd",NULL);

dispatch_release(queue);//非ARC模式下手动释放创建的队列

并发队列

GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建

使用dispatch_get_global_queue函数获得全局的并发队列

函数原型:
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags)

priority:队列优先级,flags:保留的参数-传0即可。

priority代表全局队列的优先级,有以下几个选项
全局并发队列的优先级

  • #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
  • #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)
  • #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
  • #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
  • 各种队列的执行效果
全局并发队列 手动创建串行队列 主队列
同步(sync) 没有开启新线程,串行执行队列 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务
异步(async) 有开启新线程,并发执行任务 有开启新线程串行执行任务 没有开启新线程,串行执行任务

GCD

1.dispatch_async

1.为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些耗时的操作,处理完成之后在主线程更新UI界面。(记住UI的更新只能在主线程哦)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)),^{ NSURL *url = [NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/h%3D200/sign=a7b8619c4e540923b569647ea259d1dc/50da81cb39dbb6fd786f7a990e24ab18972b375c.jpg"]; NSData *data = [[NSData alloc]initWithContentsOfURL:url]; UIImage *image = [[UIImage alloc]initWithData:data]; if(data != nil && image != nil){ dispatch_async(dispatch_get_main_queue(),^{ self.imageView.image = image; } } }

2.获取global_queue(并行队列)

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

3.获取main_queue(串行队列)

dispatch_queue_t mainQueue = dispatch_get_main_queue();

2.dispatch_group_async

dispatch_group_async可以监听一组任务是否完成,完成后得到通知执行其他的操作。比如你进行了2个下载任务,当这2个下载任务都完成后你通知界面刷新UI。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group,queue,^{ [NSThread sleepForTimeInterval:1]; NSLog(@"one"); } dispatch_group_async(group,queue,^{ [NSThread sleepForTimeInterval:2]; NSLog(@"two"); } dispatch_group_notify(group,dispatch_get_main_queue(),^{ NSLog(@"updateUI"); } dispatch_release(group);

diapatch_group_async是异步的方法,运行结果如下

  • one
  • two
  • updateUI

可以看到在打印完onetwo之后再打印的updateUI

3.dispatch_barrier_async

dispatch_barrier_async是在前面的任务执行完毕之后才开始执行的,同理要等它执行完毕之后,它后面的任务才会开始执行。

dispatch_queue_t queue = dispatch_queue_create("gcdDemo",DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue,^{ [NSThread sleepForTimeInterval:2]; NSLog(@"dispatch_async_after_2s"); }) dispatch_async(queue,^{ [NSThread sleepForTimeInterval:4]; NSLog(@"dispatch_async_after_4s"); }) dispatch_barrier_async(queue,^{ NSLog(@"dispatch_barrier_async"); [NSThread sleepForTimeInterval:4]; }) dispatch_async(queue,^{ [NSThread sleepForTimeInterval:1]; NSLog(@"dispatch_async_after_1s"); })

注意看打印的时间:

打印时间 打印内容 说明
16:20:33.900 dispatch_async_after_2s 在33s的时候打印的
16:20:35.900 dispatch_async_after_4s 在35s的时候打印的,和上一个打印相差2s=(4s-2s)
16:20:35.900 dispatch_barrier_async 在35s的时候打印的,是在上一个结束之后打印的
16:20:40.900 dispatch_async_after_1s 在40s的时候打印的,在上一个打印结束之后,睡了4s后又睡了1s才打印的,所以和上一个打印相差5s=(4s+1s)

4.dispatch_apply

执行某个代码片段N次

dispatch_apply(N,globalQ,^(size_t index){ //执行N次 });

NSString类的实现

+(id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding{ NSString *obj; obj = [self allocWithZone:NSDefaulMallocZone]; obj = [obj initWithCString:nullTerminatedCString encoding:encoding]; return AUTORELEASE(obj); }

static关键字的作用

  • 函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值;
  • 在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
  • 在模块内的 static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内;
  • 在类中的 static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
  • 在类中的 static成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static成员变量。

#import和#include的区别?

  • #importObjective-C导入头文件的语法,可保证不会重复导入。
  • #includeC/C++导入头文件的语法,
  • 如果是Objective-CC/C++混编码,对于C/C++类型的文件,还是使用#include来引入,这种写法需要添加防重复导入的语法。

@class的作用

@class一般用于头文件中通过前向声明,就可以声明了,但是在.m文件中还是需要使用#import进来的。它的作用只是前向声明。

property属性的修饰符有什么样的作用

参考链接来自标哥的技术博客:http://www.henishuo.com/ios-property/

  • getter=getNamesetter=setName:设置settergetter的方法名
  • readwritereadonly:设置可供访问级别
    -assign:方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题
  • retain:其setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序
  • copy:其setter方法进行copy操作,与retain处理流程一样,先对旧值release,再copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
  • nonatomic:非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。

obj在编译时和运行时分别时什么类型的对象

NSString *obj = [[NSData alloc] init];

在编译时,我们所声明的objNSString *类型,因此是NSString *类型对象。在运行时,由于指针obj所指向的是NSData *类型对象的内存,因此实际上是NSData *类型的对象。

在编译时,这一行代码会转换成类似这样:
NSString *obj = ((id (*)(id, SEL))objc_msgSend)([NSData class], @selector(alloc)); obj = ((id (*)(id, SEL))objc_msgSend)((id)obj, @selector(init));

  • 由于在编译时,转换成id,因此可以用NSString *指向NSData对象,而id
    是具备运行时特性的,因此在链接时,通过idisa指针可以找到其所属的类,因此最终类型还是通过isa确定其所属类型。

nil、Nil、NULL和NSNull区别

参考链接来自标哥的技术博客:http://www.henishuo.com/nil-nil-null-nsnull-difference/

  • NULL

    • NULLC语言中,NULL是无类型的,只是一个宏,它代表空。
    • 像C语言中,我们定义了一个指针,当我们使用完以后,通常会设置指向NULL。如果没有设置,这个指针就成了所谓的野指针,然后其它地方不小心访问了这个指针是很容易造成非法访问的,常见的表现就是崩溃了。
    • 既然Objective-C是基于C语言的面向对象语言,那么也会使用到C语言类型的指针,比如使用const char *类型,判断是否为空时,是使用p != NULL来判断的。
  • nil

    • 对于我们Objective-C开发来说,nil就代表((void *)0)。我们使用nil表示Objective-C对象为空,如NSString *str = nil
  • Nil

  • 对于我们Objective-C开发来说,Nil也就代表((void *)0)。但是它是用于代表空类的。比如Class *myClass = Nil;

  • NSNull

  • NSNull是继承于NSObject的类型。它是很特殊的类,它表示是空,什么也不存储,但是它却是对象,只是一个占位对象。

    • 比如说服务端接口中让我们在值为空时,传空。
      NSDictionry *parameters = @{@"arg1" : @"value1",@"arg2" : arg2.isEmpty ? [NSNull null] : arg2};
  • 总结

  • NULL是宏,是对于C语言指针而使用的,表示空指针

  • nil是宏,是对于Objective-C中的对象而使用的,表示对象为空

  • Nil是宏,是对于Objective-C中的类而使用的,表示类指向空

  • NSNull是类类型,是用于表示空的占位对象,与JS或者服务端的null类似的含意

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容