首页 > 系统 > iOS > 正文

iOS知识点八

2019-11-09 13:57:03
字体:
来源:转载
供稿:网友

1.请介绍一下isa指针,怎么用,用来干嘛的?

每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针 ,这个指针是指向对象的真实类型,根据这个指针就能知道将来调用哪个类的方法

每个实例对象都有个isa指针, 他指向对象的类,而类对象里也有个isa指针, 指向meteClass(元类)。元类保存了类方法的方法列表。当类方法被调用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针, 它的isa指针最终指向的是一个根元类(root meteClass),其实就是NSObject. 根元类的isa指针指向本身,这样形成了一个封闭的内循环。

2.iOS 6/7怎么适配

判断系统版本,UI可能会有差异 iOS7的状态栏是悬浮在内容区域上的,即新建一个UIViewController,它的view的frame的origin.y是从屏幕顶端开始算的,而不是从状态栏底部开始的(上移了20个像素)。

3.存储字典怎么进行

4.Socket

5.CoreData

6.内联函数

static inline 可以取代宏, 引入内联函数是为了解决函数调用效率的问题(减少了对调用方法进栈出栈时间的开销)

7.UICollectionView如何实现瀑布流

8.Autolayout

9.iOS10的新特性

10.消息推送实现原理

11.SDWebImage 内部实现过程

入口 setImageWithURL:placeholderImage:options: 会先 placeholderImage 显 示,然后 SDWebImageManager 根据 URL 开始处理图片。进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo: , 交 给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:.先从内存图片缓存查找是否有图片, 如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager 。 SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操 作,所以回主线程进行结果回调 notifyDelegate:。如果上一操作从硬盘读取到了 图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。 SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而 回调展示图片。如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片, 需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。共享或重新 生成一个下载器 SDWebImageDownloader 开始下载图片。图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载 失败。connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效 果。connectionDidFinishLoading: 数据下载完成后交给SDWebImageDecoder 做图 片解码处理。图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。 如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。

12.CoreText和CoreImage的使用

13.自定义转场动画

14.NSOperation的使用

15.@synthesize 和 @dynamic 分别有什么作用

@PRoperty 有两个对应的词,一个是@synthesize,一个是@dynamic。如果 @synthesize 和@dynamic 都没写,那么默认的就是@syntheszie var = _var; @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器 会自动为你加上这两个方法 @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生 成(当然对于 readonly 的属性只需提供 getter 即可) 假如一个属性被声明为@dynamic var,然后你没有提供@setter 方法和@getter 方 法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = instance.var 时,由于缺 getter 方 法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所 谓的动态绑定

16.KVO 内部实现原理?

KVO 是基于 runtime 机制实现的 当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一 个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。派生类在 被重写的 setter 方法内实现真正的通知机制 如果原类为 Person,那么生成的派生类名为 NSKVONotifying_Person 每个类对象中都有一个 isa 指针指向当前类,当一个类对象的第一次被观察,那么 系统会偷偷将 isa 指针指向动态生成的派生类,从而在给被监控属性赋值时执行的 是派生类的 setter 方法 键值观察通知依赖于 NSObject 的两个方法 : willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey: 一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey: 会 被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。 补充:KVO 的这套实现机制中苹果还偷偷重写了 class 方法,让我们误认为还是使 用的当前类,从而达到隐藏生成的派生类

17.简述应用程序按Home键进入后台时的生命周期,以及从后台回到前台时的生命周期?

App生命周期:   刚启动时:   application:didFinishLaunchingWithOptions:   applicationDidBecomeActive:      进入后台时   applicationWillResignActive:   applicationDidEnterBackground:      进入前台时   applicationWillEnterForeground:   applicationDidBecomeActive:    ViewController生命周期: 刚启动时: init / awakeFromNib(ViewController是从Xib加载的就会调用该方法) loadView viewDidLoad viewWillAppear: viewDidAppear:      跳转到第二个页面:   [SecondViewController init]   [FirstViewController viewWillDisappear:]   [SecondViewController loadView] [SecondViewController viewDidLoad] [SecondViewController viewWillAppear:] [FirstViewController viewDidDisappear:] [SecondViewController viewDidAppear:]

从第二个页面回到第一个页面: [SecondViewController viewWillDisappear:] [FirstViewController viewWillAppear:] [SecondViewController viewDidDisappear:] [FirstViewController viewDidAppear:]

18.XMPP?

19.远程推送原理, iOS10推送新特性?

iOS远程推送的前提是:装有我们应用程序的iOS设备,需要向APNs服务器注册,注册成功后,APNs服务器将会给我们返回一个devicetoken,我们获取到这个token后会将这个token发送给我们自己的应用服务器。当我们需要推送消息时,我们的应用服务器将消息按照指定的格式进行打包,然后结合iOS设备的 devicetoken一起发给APNs服务器。我们的应用会和APNs服务器维持一个基于TCP的长连接,APNs服务器将新消息推送到iOS设备上,然后在设备屏幕上显示出推送的消息。

详细步骤如下: 1.A用户发送手机设备的UDID和应用的Bundle ID给APNs服务器注册 2.APNs根据设备的UDID和应用的Bundle ID生成一个deviceToken返回给A 3.发送A用户的deviceToken和用户的标识(比如微信号)给应用的服务器 4.应用服务器保存进数据库 5.B用户给A用户发送了一套消息,先发送到应用的服务器,应用服务器根据唯一标识找到A的deviceToken 6.应用服务器把A的deviceToken和B发送的信息一起发送给APNs服务器 7.APNs服务器再根据deviceToken找到A用户,再把信息推送到A的手机设备,已通知的形式展示推送的信息

20.OC语言的基本特点

OC 语言是 C 语言的一个超集, 只是在 C 的基础之上加上了面向对象 (oop) 的特性; OC 与 java 语言相同都是单继承, 这一点与 C++ 语言不同(多重继承); OC 不支持命名空间机制, 取而代之的是在类名之前添加前缀, 以此来区分。

OC作为一门面向对象的语言,自然具有面向对象的语言特性,如:封装、多态、继承。它具有静态语言的特性,又有动态语言的效率。 Objective-C 具有相当多的动态特性,表现在三个方面:动态类型、动态绑定、动态加载。之所以叫做动态,是因为必须到运行时才会做一些事情。 1、 动态类型 :即运行时再决定对象的真实类型。这类动态类型在日常应用中非常常见。简单说就是id类型。实际上静态类型因为其固定性和可预知性而使用的非常广泛,静态类型是强类型,而动态类型属于弱类型。运行时决定接受者。 2、 动态绑定 :基于动态类型,在某个实例对象被确定后,其类型就被确定了。该对象的属性和响应的消息也被完全确定,这就是动态绑定。 3、 动态加载 :根据需求加载所需要的资源,这点很容易理解,对于iOS开发来说,基本就是根据不同的机型做适配。最经典的例子就是在Retina 设备上加载@2x的图片,而在老一些的普通设备上加载原图。随着Retina ipad的推出,和之后可能的Retina Mac的出现,这个特性相信会被越来越多的使用。让程序在运行时添加代码块以及其他资源。用户可以根据需要加载一些可执行代码和资源,而不是在启动时就加载所有组件。可执行代码中可以含有和程序运行时整合的新类。

21.自动释放池何时被创建,又何时被销毁?

在每一个事件周期(event cycle)的开始,系统会自动创建一个自动释放池;在每一个事件周期的结尾,系统会自动销毁这个自动释放池。一般情况下,你可以理解为:当你的代码在持续运行时,自动释放池是不会被销毁的,这段时间内你也可以安全地使用自动释放的对象;当你的代码运行告一段落,开始等待用户输入(或者其它事件)时,自动释放池就会被释放掉,池中的对象都会收到一条release消息,当对象的引用计数器为0时会被销毁。 自动释放而非直接释放,可以帮助你节省一些代码量,提高开发速度。但是它有一个直接的缺点:它延缓了对象的释放,在有大量自动释放的对象时,会占用大量内存资源。因此,你需要避免将大量对象自动释放。并且,在以下两种情况下,你需要手动建立并手动销毁掉自动释放池: 1.当你在主线程外开启其它线程时:系统只会在主线程中自动生成并销毁掉自动释放池。 2.当你在短时间内制造了大量自动释放对象时:及时地销毁有助于有效利用设备上有限地内存资源。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表