美文网首页
2019基础面试题 !!!持续跟新中

2019基础面试题 !!!持续跟新中

作者: _VisitorsZsl | 来源:发表于2020-02-19 15:21 被阅读0次

基础面试题:

1. copy 和 strong 的区别。

也就是 深拷贝和浅拷贝 的区别。 copy属于深拷贝 其性质是开辟新的内存空间指向新的值,不同的内存地址互不干涉,使⽤ copy 的⽬的是为了让本对象的属性不受外界影响。strong属于浅拷贝 那么这个属性就有可能指向⼀个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性

常会被问到!!!

1.  NSMutableArray为什么不可以用 copy 修饰?

其原因是:在调用self.数组  增删改 系统方法的时候会奔溃。 copy 修饰的  NSMutableArray的数组会被当成  NSArray 不可变数组执行, 当self 调用底层的 get/set 方法时候 没有响应的增删改方法。所以会奔溃。

经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作!

2. NSString 为什么用copy 修饰?

      使用copy修饰之后,即使属性拷贝来自可变字符串,也会被深拷贝成不可变字符串, 例如在字符串appendString 拼接或者是等等操作时。开辟的是另一块新的内存空间、修改前的值不会随着修改后的值而发生变化。所以为了避免可变字符串类型的值被修改用copy

2. 关于常见的block问题

1. block 为什么用copy修饰?

2. _ _ block 为什么可以修改block变量

3. 关于block 循环引用的问题

来自内心灵魂深处的三问!!!

block 为什么用copy修饰?

首先得理解 堆和栈 的关系!  堆是程序员 手动的分配和释放内存、栈是由 系统分配释放内存。

      在MRC的时候 block所持有的对象内存是默认在栈区的、栈的特点就是创建对象随着可能被销毁、一旦销毁的对象再次调用就会奔溃。 用copy修饰后block会被放在堆区一般由程序员自己释放,他的生命 周期就是随着对象的销毁而结束。

ARC 下 使用 Strong、Copy 修饰 Block,都会将栈区的 Block 拷贝到堆区。

所有说block使用copy修饰 算是ARC下对于MAC的一个默认延续吧

_ _ block 为什么可以修改block变量 ?

使用了 __blcok 之后,在 block 被 copy 到堆上的同时也会将捕获的外部变量 copy 到堆上,之后便可以在 block 内部对外部变量进行修改

关于block 循环引用的问题 ?

一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。

block中使用self,self.xxBlcok或者成员变量block  导致了循环引用 。 __weakSelf来代替self解决等。  __weak __tyof (self) weakselfi =  self

这里常常会有一个延伸:  问的是AFNetWorking 中的Block使用怎么会不引起循环引用?

AF3.0 一下  AFURLConnectionOperation 里的一个请求结束之后,setCompleteBlock会把block设置为nil,来打破循环引用 .

所谓循环引用,是因为当前控制器在引用着block,而block又引用着self即当前控制器,这样就造成了循环引用。AFN中的block的调用并不在当前控制器中调用,那么这个self就不代表当前控制器,那自然也就没有循环引用的问题

3. ios13适配问题

1. 私有方法 KVC 可能导致崩溃。在 iOS 13 中部分方法属性不允许使用 valueForKey、setValue:forKey:  来获取或者设置私有属性,具体表现为在运行时会直接崩溃

2. 使用 presentViewController 方式打开视图,默认的如下图所示的视差效果,通过下滑返回。解决方法就是将    modalPresentationStyle  改回 Fullscreen 样式

3.MPMoviePlayerController 被弃用

4.在 iOS 13 中,苹果将原来蓝牙申请权限用的 NSBluetoothPeripheralUsageDescription 字段,替换为 NSBluetoothAlwaysUsageDescription 字段。

5. 第三方登录中心必须接入苹果登录

等等有一些导航栏 搜索框的改变 这上面我就不一一列举了。有心得同学可以自己去查阅一下文档

4. Runloop的简单理解

第一次获取时被创建、线程结束被销毁。  多线程时  主线程默认开启  子线程的手动开启

                  [NSRunLoop currentRunLoop]

概念: 运行循环机制。内部是一个do-while 不断处理各种任务(NSTimer、触摸事件、点击事件),节约CPU资源提高程序性能 ,底层是CFRunloop.

这边有一个延伸问题:  UIScrollView 的滚动会导致 NSTimer 失效为什么?

在tableview滑动时timer就是显示暂停,原因是timer的这个简便构造方法把timer加入了NSRunLoopDefaultMode上,而tableview在滑动时只会处理UITrackingRunLoopMode,也就是说当前的RunLoop并没有功夫处理timer事件。  指定消息循环的模式为CommonModes(无论runloop运行在哪个mode,都能运行)

- kCFRunLoopDefaultMode, App的默认运行模式,通常主线程是在这个运行模式下运行

- UITrackingRunLoopMode, 跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响) -

kCFRunLoopCommonModes, 伪模式,不是一种真正的运行模式 - UIInitializationRunLoopMode:在刚启动App时第进入的第一个Mode,启动完成后就不再使用

- GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到

注意iOS 对以上5中model进行了封装NSDefaultRunLoopMode;NSRunLoopCommonModes

为什么说提高了性能?

因为在没有事件发生的时候处于休眠状态,有事件发生的时候处于工作状态 。

5.  SDWebimage 原理相关问题!!!

  我这里只做一个简述。 只针对面试可能遇到的一些提问。具体问题你可以去查询一下源码或者找一些大神的博客看一看。

其作用:  就是图片的下载、缓冲、下载进度监控。

1. 缓冲图片的名称  MD5  为防止重名

2.内存警告是如何处理的 ?  利用通知中心观察 、clear Memory清理内存缓冲 clear Disk 清理磁盘缓冲。

3.缓冲时间是一周

4.clear和clean的区别?

  clear 连同缓冲文件夹删除、再创建一个新的。clean 先删除过期的文件、再计算缓冲大小删除、按照创建时间删除知道maxsize

5.默认缓冲文件路径  :  default下  6. 最大并发数6条  7.超时时间15S  8.缓冲机制:NSCache

SDWebimage的工作流程:

  1.  setImageWithURL  先设置请求网址和占位图片

  2.  先从内存图片查找图片, 如果查到回调到 SDWebImaFFgeManage中显示图片

  3.  如果有没查到就 生成opeartion 添加到队列查找磁盘、根据 URLKey从缓冲目录读取。读取到添加到内存缓冲中、再回调到manage类中展示

  4. 如果没换没有查询到 就重新下载

  5. 下载完的图片加入缓存中,并写入到磁盘中;

  6.整个获取图片的过程是在子线程中进行,在主线程中显示。

6. weak如何实现自动赋nil?

runtime 对注册的类会进行布局,weak对象会被放到一个hash中。用weak指向的对象内存地址作为key。当此对象的引用计数为0的时候dealloc,在这个weak表中搜索找到所有以key为键weak的对象从而设置为nil

7.自动释放池问题

  常用到是for循环创建大量变量的时候 !!!

每次调用每次都会创建一个新的对象。如果不是通过alloc、new、copy等创建的,那么他们的内部都会有一个autorelease进行自动释放,会等到循环结束进行释放而此时会消耗大量内存资源造成内存溢出。运行缓慢 。autorelease实际上只是把对release的调⽤延迟了,对于每⼀个autorelease,系统只是把该Object放⼊了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调⽤Release。

@autoreleasepool  可以完美的解决

8.  涉及到地图持续定位耗电问题解决方案

  原因是:持续的调用didupdatelocation方法

解决方案“:

1. 距离过滤器  distanceFilter 指定距离调用代理方法

2. 设置精确度  通过计算过程的降低达到省电

9. set/get  方法返回self属性奔溃

self.  实际上相当于 set/get 的调用。  导致循环调用  所以会奔溃

11. KVO原理

因为时间问题我就不贴代码了。只是将KVO建立观察者后 的一个流程梳理一下。

1、利用RuntimeAPI动态生成一个子类NSKVONotifying_XXX,并且让instance对象的isa指向这个全新的子类

2、当修改对象的属性时,会在子类NSKVONotifying_XXX调用Foundation的_NSSetXXXValueAndNotify函数

3、在_NSSetXXXValueAndNotify函数中依次调用

  1)  willChangeValueForKey        2)父类原来的setter    3)didChangeValueForKey,didChangeValueForKey:内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)

    2、如何手动触发KVO方法

手动调用willChangeValueForKey和didChangeValueForKey方法

  3、直接修改成员变量会触发KVO吗

不会触发KVO,因为KVO的本质就是监听对象有没有调用被监听属性对应的setter方法,直接修改成员变量,是在内存中修改的,不走set方法

4、不移除KVO监听,会发生什么

不移除会造成内存泄漏但是多次重复移除会崩溃。系统为了实现KVO,为NSObject添加了一个名为NSKeyValueObserverRegistration的Category,KVO的add和remove的实现都在里面。在移除的时候,系统会判断当前KVO的key是否已经被移除,如果已经被移除,则主动抛出一个NSException的异常


11.  delegate 代理用weak 修饰?

weak修饰对象只指向对象,并不保持delegate对象,释放由外部控制

strong该对象强引用delegate对象,形成稳妥对象和被委托对象相互拥有,由于外部不能销毁而导致引起循环引用问题。

12. 关于图片的上传和压缩问题

AF中的 AFHTTPSessionManager就可以实现。主要涉及的就是如果是多张图上传50张、500张考虑一个占用内存过大而崩溃的问题,可以通过加到自动释放池解决。

压缩问题:  例如传的图片大、耗时  耗流量

可以通过 UIImageJPERepresontation方法。可以设置压缩指数。 例如加入判断  image>1M 压缩指数设置为0.7  0.5M<imahe<1M 调整成0.8  小于0.5M 写成0.9或者1 都可以

13.TableView优化

1.提前计算好cell的高度和布局(因为tableview回调的时候会多次的调用heightForRow的方法),获取数据的时候计算cell,保存到对应的model中,调用行高直接获取model 就行

2.数据量大的时候异步加载的方式进行加载 ,避免堵塞主线程

3.滑动时按需加载对应的内容,


14.性能优化

1. 页面布局:  对象的创建、销毁(广播、定时器等等),文本控件的计算排版等等

2.卡顿优化: 2.1 尽量提前计算好布局,一次性调整对应属性避免多次修改

                        2.2 使用多线程。如果线程开辟太多的话可以结合信号量(消耗CPU)

                        2.3  数据量大的时候考虑使用本地数据(尽量一次性写入,避免频繁写入数据)

3. 网络优化:  1.  E网、4G、WiFi下设置不同的超时时间

                            2. 使用断点续传,网络不稳定的手可能会出现多次传输相同的内容到服务器

                            3. 使用缓冲减少网络请求

4. 耗电优化: 1.涉及到定位尽量不要使用实时请求,定位精度尽量不要太精确

                          2.涉及到蓝牙 、广播等等 设置一个合理的请求时间

6.内存优化: 1. 涉及到通知、定时器等等释放的问题

                        2. tableview. 行高了提前计算避免多次调用行高方法,数据大分页显示

                        3. 图片处理,尽量和UIImageView大小相同避免运行中缩放,多做缓冲

                        4.  大量的临时对象加入Autorelease Pool中执行,避免内存过高

                        5.  数据库的储存问题

15.  信号量

应用场景:  访问有限的资源、 或者是多线程中的一些特定请求

主要用到的函数:  dispatch_semaphore_create创建信号量设置初始值

                                  dispatch_semaphore_signal  发送信号,信号量+1

                                    dispatch_semaphore_wait  等待信号 , 如果大于零则减掉1个信号量,往下执                                        行,如果等于零则阻塞该线程

1. 多个网络请求无序返回后再刷新界面?

                        创建线程组dispatch_group_create,最后再notify中刷新界面。结合信号量使用这样可                          以保证在没有所有数据返回之前,notify里的内容一直不会执行

2.  多个网络请求有序返回输出?

          1.信号量

            2. 用NSOPerationQueue中的依赖关系 [ A  addDependency:B ]

16. 关于折线图、柱形、饼状图

Chares 图标库(swift写的),需要创建一个桥接,oc-swift

或者是在UIView函数方法drawRect中自定义贝塞尔曲线 画柱形设置(x,y,w,h)  设置填充颜色等等


17. AFNetWorking 实现原理:

      主要是用于对网络数据的请求和实时监控网络的状态,由五个部分组成:

  1. AFURLSessionManage:核心类,负责请求的建立、管理和销毁等功能

  2. AFURLRequest:  请求头的解码、序列化、优化处理、简化拼接过程

  3. AFURLRepose:  用于网络返回数据的处理

4. AFNetWork :  监控网络请求的变化

5. UIKit:对于iOS UIKit的扩展库

                                这里会常常被问到: AFN网络请求的block内使用self不会造成循环引用?

                                答案是:AFNetworking是封装了一个completionBlock,AFURLConnectionOperation 里的一个请求结束之后,setCompleteBlock会把block设置为nil,来打破循环引用 .

18. 沙河目录分析:

分为三个目录:  Documents、 Library( Caches、Preferences )、 tmp

Documents:保存应用运行需要持久化的数据,  sqlite数据库

tmp: 保存运行时所需的临时数据

Library-->Preferences :  NSUserDefaults

20. HTTPS 协议

1.向后台开发者获取SSL证书(crt格式),并将该文件的格式转换成cer格式

2.  双击该文件,在 keychain (钥匙串访问)中找到该文件的证书,项目然后导出cer文件。

3.  AFN 3.0配置  先导入证书 证书由服务端生成,使用证书验证模式。 如果是需要验证自建证书,

4. info.plist,配置白名单

22.  runtime面试题

OC的动态性就是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数

说说OC的消息机制?

1) OC中的方法调用其实都是转成了objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)

2)objc_msgSend底层有3大阶段

          2.1消息发送:

              2.1.1.通过方法名字去 类对象 方法缓存中查找,如果有则返回方法地址

              2.1.2.如果没有缓存,则会遍历 方法列表查找

              2.1.3.查到了方法返回,并添加到 缓存列表

              2.1.4.如果没找到则会去父类缓存中查找,在去父类方法列表中查找,一层一层父类往上找

          2.2动态方法解析

            如果是 对象方法调用会 调用_class_resoveInstanceMethod()如果是 类方法调用 调用                          _class_resoveClassMethod()

          2.3消息转发

              -(id)forwardTargetForSelector:(SEL) aSelector

              -(void)forwardInvocation:(NSInvocation *)anInvocation

runtime具体应用?

1)分类添加方法   2)字典转模型 3)KVC/KVO    4 ) 方法交换

method swizzling 方法交换:

23.  load 和initalize 区别

load: 在main函数之前通过函数内存地址调用。程序启动时候加载所有的类、每个类只调用一次。不需要继承父类实现。

initalize: 在main函数之后通过objc_msgSend调用。

load和initialize方法都不用显示的调用父类的方法而是自动调用,即使子类没有initialize方法也会调用父类的方法,而load方法则不会调用父类。

24. 分类不能添加属性的原因

分类里添加属性,只是将该属性添加到该类的属性列表,并声明了setter和getter方法,但是没有生成相应的成员变量,也没有实现setter和getter方法。所以说分类不能添加属性 ,如果手动实现的话 改变内存的分布情况,这对编译性语言是灾难,是不允许的 。

分类只能扩展方法(属性仅仅是声明,并没真正实现)

25 事件的响应流程Fr

1.首先通过 hitTest:withEvent: 确定第一响应者,以及相应的响应链

2.判断第一响应者能否响应事件,如果第一响应者能进行响应则事件在响应链中的传递终止。如果第一响应者不能响应则将事件传递给 nextResponder也就是通常的superview进行事件响应

3.如果事件继续上报至UIWindow并且无法响应,它将会把事件继续上报给UIApplication

4.如果事件继续上报至UIApplication并且也无法响应,它将会将事件上报给其Delegate

5.如果最终事件依旧未被响应则会被系统抛弃

26 单元测试

介绍: 主要是xcode自带的XCTest. 简单应用场景就是(测试一些功能是否正常、代码的覆盖率等等,性能和逻辑的测试)例如要测试一个分享功能,避开重启APP进入分享界面、点击分享输入分享内容这一些列繁琐的操作。  测试很简单、主要是看自己架构设计

- [ setup ] 测试用例初始化方法 执行之前调用

- [ textXXX ] 要测试的实例方法,以text开头不含任何参数,测定预期值

- [ tearDown ] 清楚测试方法, 执行之后被调用

逻辑测试:testLogic 方法 里面  XCTAssertEqual 设定预期值验证

性能测试:testPrefromanceExample 方法  block里面做操作设置性能值选择代码通过率

异步测试:testAsync方法

UI测试: 这个是运行程序自动生成测试代码验证

27 KVC 简单分析

当一个对象调用setValue方法时,方法内部会做以下操作:

1). 检查是否存在相应的key的set方法,如果存在,就调用set方法。

2). 如果set方法不存在,就会查找与key相同名称并且带下划线的成员变量,如果有,则直接给成员变量属性赋值。

3). 如果没有找到_key,就会查找相同名称的属性key,如果有就直接赋值。

4). 如果还没有找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。

28 KVO 简单分析

KVO-键值观察机制,原理如下:

1.当给A类添加KVO的时候,runtime动态的生成了一个子类NSKVONotifying_A,让A类的isa指针指向NSKVONotifying_A类,重写class方法,隐藏对象真实类信息

2.重写监听属性的setter方法,在setter方法内部调用了Foundation 的 _NSSetObjectValueAndNotify 函数

3._NSSetObjectValueAndNotify函数内部a) 首先会调用 willChangeValueForKeyb) 然后给属性赋值c) 最后调用 didChangeValueForKeyd) 最后调用 observer 的 observeValueForKeyPath 去告诉监听器属性值发生了改变 .

4.重写了dealloc做一些 KVO 内存释放

29 button防止多次点击

1.  设置enabled或userInteractionEnabled属性

2.  借助cancelPreviousPerformRequestsWithTarget:selector:object实现

// 此方法会在连续点击按钮时取消之前的点击事件,从而只执行最后一次点击事件+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;

// 多长时间后做某件事情- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;

3.  通过runtime交换方法实现

  {           

1 创建一个UIButton的分类,使用runtime增加public属性cs_eventInterval和private属性cs_eventInvalid。         

2 在+load方法中使用runtime将UIButton的-sendAction:to:forEvent:方法与自定义的cs_sendAction:to:forEvent:方法进行交换         

3 使用cs_eventInterval作为控制cs_eventInvalid的计时因子,用cs_eventInvalid控制UIButton的event事件是否有效。 

  }

30 WKWebview

WKWebview的白屏的问题:

原因:1. WKWebview是一个多进程组件,内存占用太大的时候会在加载中奔溃导致白屏。2. 网络问题。

解决:1.清理缓冲 重新加载 iOS 9以后 WKNavigtionDelegate 新增了一个回调函数。-(void)webiewXXXTermi nate方法在即将出现白屏的时候回调用这个方法。里面执行[webview reload]

WKWebView设置自定义UserAgent:

  1. WKWebView的customUserAgent会覆盖webview本身的userAgent;2.configuration.applicationNameForUserAgent设置的userAgent是拼接在webview本身的userAgent后面的。

正确设置自定义userAgentWKWebViewConfiguration *configuration = [WKWebViewConfiguration new];configuration.applicationNameForUserAgent = "iOS";_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

使用方法:WKWebView来加载网页,使用WKWebViewConfiguration来配置JS交互。

js调用OC

1. 主要使用WKUserContentController,用来做 原生与JavaScript的交互管理

2.使用协议类WKScriptMessageHandler,用来处理监听JavaScript方法从而调用原生OC方法。

3. 通过 接收JS传出消息的name 进行捕捉的回调方法

OC调用JS

使用WKUserScript,执行自定义的JavaScript代码

31 MVVM

MVVM就是在MVC的基础上分离出业务处理的逻辑到viewModel层,

即:model层,API请求的原始数据、数据持久化view层视图展示,由viewController来控制viewModel层,负责?络请求、业务处理和数据转化简单来说,就是API请求完数据,解析成model,之后在viewModel中转化成能够直接被视图层使?的数据,交付给前端。经过viewModel转化之后的数据由viewModel保存,与数据相关的处理都将在viewModel中处理。viewModel返回给view层view层是由viewController控制的。view层只做展示,不做业务处理。view层的数据由viewModel提供。

32 什么时候会报unrecognized selector的异常?

objc在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行,如果,在最顶层的父类中依然找不到相应的方法时,会进入消息转发阶段,如果消息三次转发流程仍未实现,则程序在运行时会挂掉并抛出异常unrecognized selector sent to XXX 。

33  runtime如何通过selector找到对应的IMP地址?

每一个类对象中都一个方法列表,方法列表中记录着方法的名称,方法实现,以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现.

34 objc在向一个对象发送消息时,发生了什么?

objc在向一个对象发送消息时,runtime会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行,如果一直到根类还没找到,转向拦截调用,走消息转发机制,一旦找到 ,就去执行它的实现IMP 。

35  AutoreleasePool自动释放池

AutoreleasePool(自动释放池) 是OC中的一种内存自动回收机制,在释放池中的调用了autorelease方法的对象都会被压在该池的顶部(以栈的形式管理对象)。当自动释放池被销毁的时候,在该池中的对象会自动调用release方法来释放资源,销毁对象。以此来达到自动管理内存的目的

36  APP的启动

APP的冷启动可以概括为3大阶段:dyld、runtime、main

1. dylddyld(dynamic link editor),Apple的动态链接器,可以用来装载Mach-O文件(可执行文件、动态库等)。启动APP时,dyld所做的事情有:装载APP的可执行文件,同时会递归加载所有依赖的动态库.当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行下一步的处理.

2. runtime启动APP时,runtime所做的事情有:调用map_images进行可执行文件内容的解析和处理在load_images中调用call_load_methods,调用所有Class和Category的+load方法进行各种objc结构的初始化(注册Objc类 、初始化类对象等等)调用C++静态初始化器和attribute((constructor))修饰的函数

3. main接下来就是UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法

4. APP启动优化

37  @synthesize/@dynamic

@synthesize 表示如果属性没有手动实现setter和getter方法,编译器会自动加上这两个方法。@dynamic  告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。

38 埋点

Flurry:  埋点类——方法列表部署

39  GCD

GCD会自动管理线程的生命周期, 比如创建线程, 调度任务, 销毁线程等等操作.

同步执行: 在GCD里是sync, 不会开启新线程, 只会在当前线程进行操作.

异步执行: 在GCD里是async, 可以另外开启一个新的线程执行任务.

并行队列: 全名为Concurrent Dispatch Queue, 指的是可以让多个任务同时执行, 如果用到并行队列的话, 是会自动开启多个线程同时执行任务

.串行队列: 全名Serial Dispatch Queue, 指的是任务一个接一个的执行, 完成了前面的那个就到后面那个, 和我们刚刚举的收费站例子一样.

使用方法:

这里可以使用dispatch_queue_create来创建对象, 这里需要传入两个参数

.第一个参数: 队列的唯一标识符

第二个参数: 队列的类型, DISPATCH_QUEUE_SERIAL表示串行队列,

                                        DISPATCH_QUEUE_CONCURRENT表示并行队列.

常用方法:

dispatch_after  设置延迟在多少秒后执行

dispatch_get_global_queue 会获取一个全局队列,

dispatch_get_main_queue 会返回主队列

dispatch_once 一次性执行 只执行一次

40 单例

优点: 1.不用再频繁地创建和销毁对象,从而提高了系统的性能和节约系统资源 

            2. 单例对象可以做到按需创建对象或加载资源,以节省不必要的内存。

缺点:  1. 由于单利模式中没有抽象层接口,  单例类很难再进行扩展

            2.单例对象长时间不被利用,系统有可能会认为是垃圾而被回收,这将导致当前单例对象状态的丢失。

41 TableView为什么不响应touchBegan

通过响应链我们不难想象到,当我们点击屏幕时,第一响应者应该是UITableView,而我们调用的touchBegan其实是ViewController的View的方法,所以无法被调用。

UITapGestureRecognizer添加手势实现方法作处理。  手势方法实现

/**     判断当前点击的位置是否处于 collectionView 对象内,如果是,则返回 NO 以使 UITapGestureRecognizer 手势对象失效    

if ([touch.view isDescendantOfView:self.collectionView]) {

    return NO;

    }

    return YES;

42 加密方式

MD5  base64   AES  DES

相关文章

网友评论

      本文标题:2019基础面试题 !!!持续跟新中

      本文链接:https://www.haomeiwen.com/subject/lxuafhtx.html