定时器的实现方式 1.GCD:dispatch_time 2.NSTimer scheduledTimerWithTimeInterval NSTImer timerWithTimeInterval 3,CADisplayLink

collection layoutSizeForItemAtIndexPath即可实现瀑布流和每行多个cell的横排tableview

tableview 的流畅度的如何提升?

1.每次都检查有无重用cell,尽量不重新创建cell

2.cell 里尽量使用drawRect画而不使用UIView

3.图片载入放入后台进程 4.cell数据尽量提前缓存好,不读现用现去读文件

5.数据量大的尽量做一个load more cell 出来,避免边滚边读 定时器的实现方式 1.GCD:dispatch_time 2.NSTimer scheduledTimerWithTimeInterval NSTImer timerWithTimeInterval 3,CADisplayLink

###常用框架

CoreData.framework: 数据库coreData

corelocation.framework:地图定位
mapkit.framework:地图显示

CoreAnimation.framework:动画

AddressBook.framework:通讯录

AVfoundation.framework:流媒体
OpenAi.framework:播放音频流

CFNetwork.framework:网络通信(套接字)
Coretelephony.framework:访问电话相关的信息,比如运营商,信号强度等,
CoreText.framework:图文混排
Gamekit.framework:实现蓝牙相互通信,即是服务端,又是客户端
Social.framework:社会化分享(新浪,QQ,微信)
MessageUI.framework:发短信,发邮件
newsstandKit.framework:反台下戴

###MVP

####概念

是MVC模式的一个演化版本,全称Model-View-Presenter。

Model:主要提供数据的存储功能,一般都是用来封装网络获取的json数据的集合。Presenter通过调用Model进行对象交互

View:这个View可以是viewcontroller、view等控件。Presenter通过向View传model数据进行交互。

Presenter:作为model和view的中间人,从model层获取数据之后传给view,使得View和model没有耦合

###好处

Presenter:作为model和view的中间人,从model层获取数据之后传给view,使得View和model没有耦合

View不直接与Model交互,而是通过与Presenter交互来与Model间接交互。

Presenter与View的交互是通过接口来进行的。

通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。

###概念图

###逻辑图

###实际项目思路图

###项目文件结构

看出一个模块有4个文件夹,model,controller,presenter,view

###MVP总结 mvp 真正的打断了了m v 的交互,

通过p作为中间桥梁,p请求数据,然后组建模型,通知v 刷新,

v 可以是viewcontroller 也可以是view ,而且v与p一一对应,是将部分的v的业务逻辑放入p中处理,并且v不处理任何数据,只负责视图展示和通过新的模型数据刷新,

对于一些v的操作,可以直接发送给p处理,p主要处理业务逻辑,v仅仅负责展示和刷新

###关于范型编程

T是Type

E是Element

E一般用来表示集合类型中的元素的类型,例如List接口的定义,public interface List extends Collection

###block 和Delegate

使用delegate的目的是使业务逻辑划分更清晰,保证一个函数只做一件事情

使用block会导致这个小方法结合到一个函数里,不利于代码维护

MVVM

###引入MVVM的初衷

主要是为了解决在开发过程中Controller越来越庞大的问题,变得难以维护,

所以MVVM把数据加工的任务从Controller中解放了出来,

使得Controller只需要专注于数据调配的工作,

ViewModel则去负责数据加工并通过通知机制让View响应ViewModel的改变。

###MVVM的本质

严格来说MVVM其实是MVCVM。

Controller夹在View和ViewModel之间做的其中一个主要事情就是将View和ViewModel进行绑定。

在逻辑上,Controller知道应当展示哪个View,Controller也知道应当使用哪个ViewModel,然而View和ViewModel它们之间是互相不知道的,所以Controller就负责控制他们的绑定关系.

###MVVM实现原理

在MVC的基础上,把C拆出一个ViewModel专门负责数据处理的事情,就是MVVM。

然后,为了让View和ViewModel之间能够有比较松散的绑定关系,于是我们使用KVO,Notification,block,delegate和target-action都可以用来做数据通信,从而来实现ViewModel和View的绑定.

###MVVM布局图及各部分功能

(View/ViewController - ViewModel - Model)

View - 用来呈现用户界面,可能是一个view 也可能是一个viewController

Controller - 负责ViewManger和ViewModel之间的绑定,负责控制器本身的生命周期。

ViewModel - 存放各种业务逻辑和网络请求

Model - 用来呈现数据

目的

保持View和Model的高度纯洁,提高可扩展性和复用度

ViewModel是为了拆分Controller业务逻辑而存在的,所以ViewModel需要提供公共的服务接口,以便为Controller提供数据

>

View进行自己所负责的视图数据绑定工作

Controller负责将ViewModel和ViewManger进行绑定,进行数据转发工作。

###MVVM好处

View很纯洁,需要复用View,若业务逻辑变化则切换ViewManger。

ViewManger也比较纯洁,若业务逻辑不变,而View需要大变,则切换View即可,保证View中的protocol或者block一致即可<最好是通过协议提前规范好>。

这样就实现了互相的封装,两者之间只通过protocol或者block进行交流通信,降低了代码的耦合度。尽量使用protocol和category来制定对象之间的通信规范,来降低代码的侵入性。

###一句话小知识

释放后置nil 是安全释放

float x 与“零值”比较的if语句。

     if(x>0.000001&&x<-0.000001)

oc默认访问权限是protect。C++默认访问权限是private

NSFileManager:文件管理者,针对文件系统,比如文件的删除,重命名,移动等操作

NSFileHandle:文件操作者,针对单独的文件,比如文件内容的修改,追加等

oc中类无静态成员

AutoLayout是IOS6之后引进的自动布局功能,通过勾选AutoLayout设置各种Constraint约束来实现在不同设备和不同方向上的自动布局。

[NSNotification postNotification]:发出的消息和接受消息的事件在同一个线程中。

如果发送消息的是主线程,则接受消息的处理会使主线程阻塞, 如果发送消息的是子线程。可以避过主线程的阻塞

OC的.语法是调用一个方法,调用的实质是变量的setter/getter方法

viewWillAppear添加的东西必须在viewWillDisAppear移除。目的保持各界面的独立性

oc中类的复用关系为单一继承(super关键字的意义),并且只有共有继承,想实现多继承,可以用protocol来模拟实现

子类从新定义父类的方法称为重载,但是无需任何关键字

plist是保存程序相关的属性,叫做属性列表

selector:方法选择器,是一个方法名称,本质跟c的回调函数一致,主要是用于对象之间进行松耦合的通讯。

IBOutlet关键字,它用于通知interface builder将一个实例变量当成插座变量,从而可以与文件的拥有者(视图控制器)进行关联

IBAction关键字,它的作用是告诉interface builder 将某个方法当成目标/动作关联中的动作

block:匿名代码段,实现原理是:oc对c的扩展,基于指针和函数指针来实现的

指针:一种数据类型,用于存储一个对象的地址,占四个字节

非正式协议:NSObject的类别,创建一个NSObject的类别叫创建一个非正式协议

xmpp:基于xml协议,又名可扩展消息处理现场协议,是即时通信协议,

git开源的xmpp框架和免费的服务器openfire即可以实现小型的即时通信。

###一个参数既可以是const还可以是volatile吗?

可以,比如:只读的状态寄存器。它是volatile因为它可能被意想不到地改变。

它是const因为程序不应该试图去修改它

###+(void)load; +(void)initialize;有什么用处?

二者都是runtime自动调用的,且只会调用一次,

load 在viewcon的初始化是调用,

initalize在初始化完成后第一次调用类方法或实例方法时调用

###离层渲染

就是离开屏幕,在另一块内存中渲染。非常好内存,因为直接牵扯到2个上下文环境的切换(屏幕环境和屏幕外缓存环境)

###输入源和输出源 插入带麦耳机后,

输入源共有2个:内置麦克风.耳机麦克风

输出源有3个:

打电话时用的,在上面的那个输出(Built-In Receiver)、

耳机(Wired Headphones)

放音乐时用的内置扬声器(Built-In Speaker),

用户在插入带麦耳机后,会自动将输入源切换到耳机麦克风,将输出源切换到耳机。

而且,在输入源是耳机麦克风的时候,将输出源切换到耳机是强制的

###self.caption = nil 与 __caption = nil的区别

self.caption 会对caption的setter方法,其中设计到了原有对象的释放,可以避免内存泄露

而caption = nil不会

###为什么要使用空模板

因为它提供了一个简单的、带有一个窗口的应用程序。这是一个应用程序所需的最小框架,你可以用它作为开始来编写你自己的程序。

###NSUserDefaults 存入对象注意事项

1.必须存入一个自己创建的对象。

如果存入的是从NSUserDefaults取出一个对象,不管你是不是对取出的对象做修改。都会导致 存入崩溃,报的错误是过度释放。

2.自定义数据类型的存储

可使用对象的归档和解归档实现。即对象归档为NSData然后存入

###声明,定义

声明不会分配内存。

定义才分配内存,

不分配内存则就没办法存储数据,

所以NSArray等容器内对象使用前必须alloc,分配内存或者采用系统返回的autorelease对象来分配内存

###什么是KVC和KVO? KVC(Key-Value-Coding)

就是object的setValue forKey机制,是一种键 - 值编码,用于间接访问对象的属性,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。

KVO(Key-Value- Observing):

用于监听一个属性值的变化,当指定的对象的属性被修改了,允许对象接收到通知的机制 KVO是基于KVC实现的

###类别的作用?继承和类别在实现中有何区别? category

有名类别,分类,用于给原类添加新方法,不会产生新类, 如果重写原类的方法。则原类的方法被覆盖。

注意不可以添加新的属性

继承

属性和方法都可以添加,但会产生新的类

类别主要有2个作用:

(1)将类的实现分散到多个不同文件或多个不同框架中。(比如系统NSData和NSString等对NSObject的setValue ForKey方法的实现)

(2)向对象添加非正式协议(即向类添加NSObject的分类)。

###类别和类扩展的区别。 类别:

仅用于添加方法

类扩展:

可添加方法和属性,主要用于定义私有方法和属性,一般写.m文件中,没有专门的实现类

类别和类扩展格式

类扩展@interface ICSWLoginViewController ()
类别:@interface NSData (NSDataBase64Additions)

###dealloc中怎么查看某一个控件是否被释放呢?

CFGetRetainCount(( __bridge CFTypeRef)(obj))

就是把oc对象转化为CF对象,然后使用CF对象的CFGetRetainCount查看引用计数,看是否为1.

###frame 和bounds区别和联系

frame当前视图的大小和位置,是以父视图的原点为参考点的

bounds是当前视图是自身坐标系的位置和大小,位置一般为0,0

改变frame的位置和大小可以改变当前视图的位置和大小

改变bounds的位置(origin)会改变其子视图的原点即参考点,为自身没有影响

改变bounds的大小(size),则当前的视图的中心点不会发生变化,而是大小以中心点为中点进行缩放。

###oc优缺点:

缺点:不支持命名空间, 用前缀实现

不支持多重继承,用协议实现

有点:动态运行时,可与c++/c混编

###oc如何和c++/c混编

cpp文件是c++代码,混编指的是,oc的实现文件可以调用c++(cpp)提供的接口

混编方法,将oc的实现文件.m文件后缀名改名mm

需要注意的事情是;c++的头问价必须采用c语言的格式声明函数。

###Foundation框架类简介

Foundation类层次的根是NSObject类,它(和=NSCopying协议一起)定义了基本的对象属性和行为。
Foundation框架的剩余部分由几组相互关联的类和一些独立的类组成。有一些代表基本数据类型的类,如字符串、字节数组;用于存储其它对象的集合类如NSArray;一些代表系统信息的类,如日期类;还有一些代表系统实体的类,比如端口、线程、和进程

###NSObject 的结构图

MacDown logo

s

###术语 Cocoa与Cocoa Touch 术语Cocoa指的是foundation 和Application Kit框架 mac开发

术语Cocoa Touch指的是Foundation和UIKit框架 ios开发

###封装 继承 多太 封装

就是一个类向外部仅暴漏共有的方法和属性。无需外接知道的方法和属性会设为私有,这位面对接口编程提供了可能。

继承

就是对父类的扩展,

多态

不同对象以自己的方式响应相同的消息的能力叫做多态。

实现原理:

1.oc中每个类都有属于该类的名字空间,类中的名字和类外的名字不会冲突,所以不同的类可以有相同的方法名。

2.oc中消息发送[target msg]的runtime会自动转化为实:objc_msgSend(target, @selector(msg),这里 selector指向的是方法的名字,并不是方法的具体实现,所以不同的类的同一方法的selector是一样的。

###方法和选择器有何不同? 选择器selector是一个方法的名字,method方法是一个组合体,包含了名字和实现.

###懒汉模式 只在用到的时候才去初始化。也可以理解成延时加载。实现主要有延时加载,避免内存过高,和异步加载,避免线程堵塞两种方式

###Weak和懒加载的关系

懒加载必须使用strong

如果用weak的话,不会产生引用,因为每次都会被释放,所以需要每次加载。

比如我用了一个UIImageView懒加载,每次都会去加载了,因为每次都会被释放

###id、nil,Nil代表什么?

id和void *并非完全一样。nil和C语言的NULL相同,

在oc中:

nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空) == NULL。

Nil定义一个指向空的类(是Class,而不是对象)。

总结nil == NULL。 nil是对象空。 Nil是类空

###https和http概念

HTTPS就是在HTTP的基础上,在传输层和会话层之间了一个SSL层,简单来说都作用是负责数据的加解密,从而保证了数据都安全。

SSL(Security Socket Layer 安全套接层) 最初1994年Netscape开发,专门用于保护Web通讯.保护浏览器和服务器之间的通信,在客户和服务器之间提供服务器鉴别、可选客户鉴别和加密通信信道。使用TCP提供一种可靠的端对端的安全服务。

###在一个https连接的网站里输入账号密码点击登录后,到服务器返回这个请求前,中间经历了什么

  1. ssl认证,即客户端和服务器的相互身份认证和确定传输的通信加密方法

服务器发证书给客户端,通过验证后,

客户端发送证书给服务器(证书中有客户端支持的加密方式),通过验证后,

服务端选择一种高级别的加密,然后用私钥加密返回给客户端,这样就完成了身份认证。

服务端证书包含的信息有公钥,加密方案及其他信息

客户端证书包含公约,支持的解密方案及其他信息

  1. 然后是一个http请求工程,会使用客户端和服务器选择的加密方式进行数据加密。

大致过程如下:

客户端把账户密码。等其他信息打包为一个请求,发送给后台,

首先会经过DNS解析器,把客户端的域名翻译为ip地址,

然后就把请求发送给IP地址所在的服务器,等待服务器的响应,

根据服务器的反应进行下一步操作。

###常用数据存储方式

嵌入式数据库数据库sqlite3

coreData

NSUserDefault(主要数据。少量的)

plist(属性列表)(小但是不主要的数据。外部拿到包可以看到这部分数据)

对象归档(NSKeyedArchiver 和NSkeyedunarchiver) (一般软件无法打开,数据就是安全,开读写文件,所以操作比较慢,),保存在本地doucument下/doucument/cache下文件,量大且需要长久存储,

保存在web服务器上或者icloud云端,需要时同步的

机密数据保存到keychain中

###什么是简单构造方法

简单构造方法就是类方法,会创建一个对象且对象会自动释放,无需关心它的生命周期,所以叫简单构造方法

###什么是延迟加载

就是懒加载,只在用到的时候去初始化加载,也叫延时加载

好处:

1.不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强

2.避免一次加载对象造成内存过高,

3.懒加载实际上实现属性的get方法,使代码之间独立性强,

注意:懒加载。必须先判断对象是否空。

###NSOperationQueue的作⽤ NSOperation调⽤start⽅法来执⾏任务,默认是同步执行的 但如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作 NSOperation Queue 是先进先出 FIFO

###层和UIView的区别是什么? 区别:图层不会直接渲染到屏幕上

联系:

UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。

它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。

UIView本身更像是一个CALayer的管理器。一个UIView上可以有n个CALayer,每个layer显示一种东西,增强UIView的展现能力。

###NSString使用copy属性原因 是为了防止传入的参数被无意中改变。copy会重新生产一个新的对象,参数传入后和传入前是2个对象,不会相互影响。

###动态判断类型

isMemberOfClass 对像是否是class类型的实例,但不包含判断是否是class子类 isKindOfClass 对象是否class类型或class子类的实例

respondsToSelector:(SEL)selector:判断类型(类)或对象是否能够响应某个方法

instanceRespondToSelector(SEL)selector判断类型(类)是否能够响应某个方法,而且这个方法用方法选择器表示

perferSeletor:(SEL)selector:用于动态调用类型或对象的一个方法

###动态加载:根据需要加载所需要的资源, 指ios中,根据不同的机型做匹配,比如,在retain设备上加载@2x图片,在iphone4等老设备上加载原图。

###Oc的程序执行过程

oc的static变量和字符串是存放在数据区的,也就是oc的数据区相当于c的静态区加上文字常量区

###oc的数据类型

###copy,MutableCopy(浅拷贝和深拷贝)方法

###oc的深浅拷贝copy/MutableCopy

copy为浅拷贝,即影子,新对象仅复制老对象的指针,新对象和老对象指向同一片内存区域

mutablecopy为深拷贝,即克隆人,复制的是对象本身,就是说复制出的对象和原对象是两个独立的对象。各有一片内存区域

特例:

对于非容器类的可变对象,mutablecopy后对象变为不可变 对于容器类对象,容器自身跟非容器对象规则相同,但容器中的元素永远是浅拷贝

###runloop 和runtime的区别

1.在oc中runloop实际是一个用来管理需要处理的事件和消息的对象。

一个runloop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件,

使用runloop的目的是让线程在有工作的时候忙于工作,而在没工作的时候出于休眠状态。

2.runtime是一种机制,又叫运行时,是指将一些决定从编译器推迟到代码运行期来处理,

在oc中所有的一切都是对象,所以runtime机制就是说;只有在运行时才能真正确定对象的相关信息,

故我们利用runtime机制可以在代码运行时获取并修改类的相关信息,比如获取类的方法列表,属性列表,添加方法.属性等。

runtime 自身由c语言实现,

###访问权限

方法:.h中默认是公有的.m默认是私有的

属性:.h中默认是公有的.m默认是私有的

成员变量:默认是私有的

###属性(@property)

属性是用来代替声明成员变量的存取方法的便捷方式

属性不会在你的类声明中创建一个新的实例变量。他们仅仅是定义方法访问已有的实例变量的速记方式而已。

###@synthesize 与@dynamic

@synthesize是系统自动生成getter和setter属性声明,不过如果开发者做了就采用开发实现的方法

@dynamic 是开发者自已提供相应的属性声明

###方法和选择器有何不同?

selector是一个方法的名字,method是一个组合体,包含了名字和实现.

###oc中可修改和不可以修改类型

个人理解就是NSArray和NSMutaleArray 。

前者创建赋值后就不可以添加新的值。或者可以添加。 就是说前者内存大小是固定的。后者内存大小是可变的

###混编arc和非arc

项目的arc为YES模式。则在非arc的文件build pharse 加-fno-objc-arc标签

项目的arc为NO模式,则在arc的文件build pharse 加-fobjc-arc标签

###.xib,storyboard,手动书写代码区别

xib(interface buider),方便对界面进行编辑。可以在窗口上面直接添加各种视图,

优点:直接看到界面的效果,操作简单。

缺点:不方便对视图进行动态控制,不灵活。

手动编写代码,继承(主要是UIView,UIViewController),

优点:可以对视图进行定制,灵活控制方便。

缺点:不能马上看到效果,复杂。

storyboard:主要用于设计主页面间的结构。

优点:可以看到界面效果,能同时进行多个界面的交互,高效快速。

缺点:不能进行进行界面的定制,不灵活。

xib和storyboard主要用于界面中的元素位置固定和清楚里面有哪些元素。

但是如果需要动态变化界面还是手动编写代码比较好。一般还是各种方式混合使用。

###开发App的步骤,开发者账号,发布app到appstore

证书分两种:主要开发者证书、发布者证书。前者开发时使用,后者发布版本时使用

(1) 模拟器调试无需代码签名;真机调试需开发者证书代码签名;发布时需发布证书签名

(2) 代码签名需要:证书+私钥,

(3) 真机调试时要求在设备上安装描述文件(provision profile),该文件包含信息:调试者证书,授权调试设备清单,应用ID。注意一个应用对应一个描述文件。

###发布app到appstore流程

1) 申请发布证书

2) 使用发布证书打包

3)在itunes上创建产品版本信息

4) 使用xcode updata to AppStore上传

5) 在itunes的build选择自己的构建版本。然后保存。

6) 在ituens上提交审核

7) 如果选择的是手动发布。则需要在审核过了之后。手动release即可

###面对对象与面对过程的概念

面向过程

就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现, 使用的时候一个一个依次调用就可以了。

面向对象

是把构成问题事务分解成各个对象,

建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

面对过程重点在解决问题的步骤

面对对象重点在各个对象的的构建和行为分析

###对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?

编译时是NSString的类型;

运行时是NSData类型的对象

###常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?

c的基本数据类型NSInteger和int

object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,

而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;

NSInteger是基本数据类型,并不是NSNumber的子类,。

NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,

NSInteger会根据系统是32位还是64来自动决定

###什么是推送消息?

推送通知是一种技术。是服务器端主动push资源给客户端

###什么时候使用NSMutableArray,什么时候使用NSArray?

当数组在程序运行时,需要不断变化(变化指的是添加和删除元素)的,使用NSMutableArray,

当数组在初始化后,便不再改变的,使用NSArray。,

###如果我们不创建内存池,是否有内存池提供给我们?

main.m文件会创建主线程的的内存池,用户创建的子线程,则需要创建该线程的内存池

###SDWebImage里面给UIImageView加载图片的逻辑

效果时设置了下载url的imageview会在图片下载完成前使用占位图片,下载完成后替换,

具体处理过程如下:

1.首先在内存中根据url为索引查找对应的缓存,找到直接显示图片

2.如果在内存中找不到,就url 的md5作为key在磁盘缓存中,找到就把数据加载内存中并显示图片

3.内存和磁盘缓存都找不到,就向服务器发起请求下载图片,下载成功后将图片存放到内存。并写入磁盘,

> 整个获取图片过程在子线程中进行,获取到图片切到主线程来显示图片

缺点:因为磁盘存储的是cache文件夹,每杀死一次进程就需要重新下载。

###设计个简单的图片内存缓存器(移除策略是一定要说的)

1.使用FMDB建立一个小型的数据库。只保存2个值。一个是图片urlmd5值,图片的本次查找时间,图片的路径固定为doucment/image/imagemd5.png

2.获取图片过程如下:

1,根据图片的md5值在在固定的文件路径下查找,找到就把图片返回。图片数据库的本次查找时间改为现在,

2,如果在固定的文件路径下找不到,就在子线程中下载,下载完成,把图片返回,并把图片数据下入到固定的那个文件路径下,然后在数据库加入一条记录

3.每个10天左右的时间,查找一次数据库,把上次使用时间在一个月的图图片路径统计处理,移除数据库的记录。并移除图片文件

###UIIImage初始化一张图片有几种方法?简述各自的优缺点。

imageNamed:系统会先检查缓存,如果没有,则先加载图像到缓存,然后再返回图像。缺点:一但创建就会占用内存

initWithContentsOfFile:系统不会检查系统缓存,而直接从文件系统中加载并返回。

imageWithCGImage:

imageWithData:网络图片的话需要子线程中执行。

###常见的加解密方式有:

RSA:基于公钥和私钥的非对称加密算法。适用范围广。

Rc4

AES:是一种对称加密的流行方式。加密涉及矩阵运算。

MD5:将任意长度的“字节串”变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,

BASE64加密

###安全有哪些方式

1)设置字符密码

2)设置手势密码

3)人脸识别

4)指纹识别

5)回答密保问题

###Framework与staticLibrary区别

Framework 是cocoa touch 中资源打包的方式,可以将实现文件,头文件,资源文件,说明文件等集中到一起,

staticLibrar打包的静态库,需要用户自己手动加入头文件,和资源文件

###为什么要用AFNetworking?

AFNetworking 目前使用比较多得一个下载库,目前一直在维护更新,使用的是非常简单,不需要添加任何关联的库。

实现原理:

下载使用的是NSURLSession,完成或错误进度回掉是block形式,管理下载是是gcd的全局串行队列,真正的部分是在gcd的block中完成的 好处:

1、带block形式

2、还对uikit 内部的类进行类别形式添加方法(异步下载图片)。

3、还可以检测网络状态。

###为什么用第三方网络库?

什么都用苹果原生的好,XML解析用苹果自带的委托,下载图片自己写,你会发现自己管理起来很复杂,很容易出错,而且性能不好。第三方网络库可以优化这些问题

###简述StoryBoard和Xib的联系和区别

xib是一个基于xml的描述文件,

storyboard是多个xib文件集合的描述文件,也采用xml格式,

一个工程中可以有多个xib文件,一个xib文件对应着一个视图控制器和多个视图。

而使用storyboard时,一个工程只需要一个主storyboard文件就可以了。

因此,在包含多个视图控制器的情况下,采用storyboard管理比较方便,而且storyboard还可以描述界面之间的导航关系。

###链表和数组的区别在哪里?

二者都属于一种数据结构

从逻辑结构来看

  1. 数组必须事先定义固定的长度(元素个数),数组可以根据下标直接存取。

  2. 链表动态地进行存储分配,链表必须根据next指针找到下一个元素

从内存存储来看

  1. (静态)数组从栈中分配空间, 对于程序员方便快速,但是自由度小

  2. 链表从堆中分配空间, 自由度大但是申请管理比较麻烦

从上面的比较可以看出,

如果需要快速访问数据,很少或不插入和删除元素,就应该用数组;

相反, 如果需要经常插入和删除元素就需要用链表数据结构了。

###页面传值都有哪些实现方式

代理传值

block传值

通知传值

属性传值

单例传值

方法传值

####import与include

import不会引起交叉编译的问题。因为在Objective-C中会存在C/C++和Object-C混编的问题,如果用#include引入头文件,会导致交叉编译。 #import<> 导入系统头文件,

import ""自己的头文件

include是C/C++中的

#import和@class的区别

@classA来引入一个类A时, 编译器只知道有这么一个类A,

但如果要是用这个class A的属性就必须加上#import“classA.h”

即import会包含这个类的所有信息,包括实体变量和方法,

而@class只是告诉编译器,其后面声明的名称是类的名称

@class循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,

如果使用#import来相互包含,那么就会出现编译错误,

如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现 只需要在。m包含需要的文件即可

###loadView是干嘛用的?

是ios给开发者自己添加view 的地方,

###iOS apns Device token的获得 以及是否会改变,解决重复推送

删除app后,再次安装就会产生新的device token

###堆和栈的区别?

管理方式:

对于栈来讲,是由编译器自动管理,无需我们手工控制;

对于堆来说,释放工作由程序员控制,容易产生memory leak。

申请大小:

栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域

堆:是向高地址扩展的数据结构,是不连续的内存区域。

分配方式:

堆都是动态分配的 ,动态分配由alloca函数进行分配

栈的动态分配由编译器进行释放,无需我们手工实现

###iOS中有三种事件类型: 分类:触摸事件,motion事件(摇一摇事件),Remote (远程控制事件)

####触摸事件:(touch) 定义:只要手指触摸屏幕,滑动,然后从屏幕离开,系统都会产生UIEvent对象类型的事件相关代理:

####远程事件 用途:主要指后台播放音乐时对进度条的控制

##cocoa中常用的设计模式

  • 组合:视图对象以协调的方式构成视图层次体系

  • 命令:目标动作机制

  • 中介者:视图控制器使用中介者模式在视图和模型之间建立双向通道

  • 策略:控制器可作为视图的策略对象,指的是视图仅执行自己展示数据的功能,将特有界面行为交给控制器。而控制器作为视图的策略对象,决定应用程序的界面行

    • 观察者 通知

    视图 ==传递用户事件== 控制器 ==更新数据== 模型

    模型 ==反应数据变化== 控制器 ==传递模型数据== 视图

mvc

####交流方式

C对M:API
M对C:Notification,KVO

C对V:Outlet

V对C:Target-action, Delegate,Datasource

####简介 MVC(Model View Controller)模型(model)-视图(view)-控制器(controller): MVC本来是存在于Desktop程序中的,M是指数据模型,V是指用户界面,C则是控制器。使用MVC是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据你可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新,从例子可以看出MVC就是Observer设计模式的一个特例。

####如何工作 MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。分层概念

#####视图: 视图是用户看到并与之交互的界面。 作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。

#####模型: 模型表示企业数据和业务规则。

#####控制器:  接受用户的输入并调用模型和视图去完成用户的需求。

#####工程中的mvc 交互逻辑图

####为什么要使用 MVC

首先,最重要的一点是多个视图能共享一个模型,现在需要用越来越多的方式来访问你的应用程序。   由于模型返回的数据没有进行格式化,所以同样的构件能被不同界面使用。 

因为模型是自包含的,并且与控制器和视图相分离,所以很容易改变你的应用程序的数据层和业务规则。

####MVC的优点

1.低耦合性    2.高重用性和可适用性

3.较低的生命周期成本

  MVC使开发和维护用户接口的技术含量降低。    4.快速的部署

5.可维护性

6.有利于软件工程化管理

####MVC的缺点

MVC的缺点是由于它没有明确的定义,所以完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。   你将不得不花费相当可观的时间去考虑如何将MVC运用到你的应用程序,同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。一旦你的构件经过了测试,你就可以毫无顾忌的重用它们了。   根据开发者经验,由于开发者将一个应用程序分成了三个部件,所以使用MVC同时也意味着你将要管理比以前更多的文件,这一点是显而易见的。这样好像我们的工作量增加了,但是请记住这比起它所能带给我们的好处是不值一提。

###单例模式(Singleton):

整个应用在运行期间只有一个某个类的实例,用于进行资源共享控制。

####优点:

a)在内存中只有一个实例,减少了内存开支。 b)可以在系统中设置全局访问点,优化和共享资源访问

####缺点:

因为单利模式不存在接口,所以扩展困难,没有完成时无法进行测试

####单利存在的问题

#####全局状态:

因为单利可以在任何地方被使用,而且不用清晰的声明从属,这意味着任何与单利交互的副作用都会影响程序中的代码

注意:ConsumerA和ComsumerB是程序中两个完全独立的模块,

但是ComsumerB中的方法会影响到ComsumerA中的行为,

因为这个状态的改变通过单例传递了过去

######生命周期

由于单例没有明确的owner(因为单例自己管理自己的生命周期),销毁一个单例是非常艰难的

所以单例只应该保持全局状态,且该状态的生命周期与程序的生命周期一致

对于单元测试:只可有一个单例ServiceRegistry,而把其他“潜在的”单例来被ServiceRegistry引用,这样其他单例拥有了一个owner,能够在进行单元测试的时候能够及时对单例进行销毁,保证了单元测试的独立性

####使用场合: 1)要求生成唯一序列号的场合(强调唯一性) 2)再整个项目需要共享访问或共享数据 3)创建易额对象需要消耗过多的资源,却有可能多次使用 4)需要定义大量的静态常量和静态方法。

####实例: UIApplication,NSBunder,NSNotificationCenter,NSFileManager等

###实现 实现GCD的dispatch_once来确保构建对象的过程在整个应用运行期间直执行一次。

//1.声明一个可以static类型的类变量
static Singleton *sharedSingleton = nil;
+ (Singleton *)sharedSingleton{
    //2.声明一个只执行一次的任务
    static dispatch_once_t once;
    //3.调用dispatch_once执行该任务指定的代码块,该代码库就是创建类的过程
    dispatch_once(&once,^{
        sharedSingleton = [[self alloc] init];
    });
    //4.返回实例化后的类对象。
    return sharedSingleton;
}

//重写copyWithZone方法
- (id)copyWithZone:(NSZone *)zone
{
    return [ instancetype  sharedDataTool];
}

###观察者模式

有称发布模式,是观察者把自己加入被观察者的一个管理队列中,当被观察者对象状态改变时,通过轮训自己的观察者队列来通知每一个正在对他进行观察的对象,这些对象根据各自要求做出相应的改变

####应用场景

一般为model层对controller的通知方式,不关心谁去接收,只负责发布信息。

###优势:解耦合

1.NotificationCenter,注册通知中心,任何位置可以发送消息,注册观察 者的 对 象可以接收。注意需要在合适的位置remove通知
2.kvo,键值对改变通知的观察者

###代理模式/委托模式

####为什么要在事件中引入委托这个概念:

事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某些其他的程序逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。

在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。.NET Framework 定义了一个特殊的类型(Delegate),该类型提供函数指针的功能。

####代理:一种通用的设计模式,用于一个对象协助另外的一个对象完成某些操作,思想是两个对象协同解决问题。 在ios中有协议,委托方,代理方,三部分组成。其中 协议:指定代理双方需做什么,可以做什么 代理方:根据指定的协议,实现委托方需要实现的功能, 委托方:也叫被代理者,是根据指定的协议,指定代理方 去完成一些功能

委托方就是被代理方,比如tableview

代理方就是实现协议的那一方,比如视图控制器。

####实现原理:

委托方保存了一个代理方的弱饮用,委托方向代理方根据协议提出需求,实际是向自己保存的弱引用发送消息。

####注意事项:

1.delegate用weak,因为代理方一般都是强引用委托方,如视图控制器和tableview,所以这个委托方不可以再强引用代理方,只能用弱应用,否则会造成循环引用。

2.单例对象千万不可做委托方,给单例设置代。会导致只有最后一个代理对象有效,

 ###ios系统层次划分从上到下(从最高层到最底层)简介

1.应用层,就是app层次

2.Cocoa Touch。触摸层(用于开发基于触摸屏的应用程序框架,包括UI元素事件分发,应用程序声明周期管理,以及基本数据类型的对象包装)

Cocoa Touch是基于oc语言的,最主要的框架是UIkit框架,应用程序项目是从Cocoa Touch开始的,

3.媒体层(用于在应用中使用各种媒体文件,进行音频和视频的录制,以及制作这种基础动画,图形绘制等包括core Graphics core Animation, openGL 等)

4.核心服务(用于访问ios的一些服务,比如定位,core Data,地址薄,GCD,网络等)

5.核心操作系统层(包括内存管理,电源管理,文件系统,安全等操作系统任务,是直接与硬件设备交互的,app开发者不会涉及到这一层)

网络电话: 概念: 网络电话,就是VOIP(voice over internet protocol)),俗称 ip电话,是通过互联网直接拨打对方的固定电话和手机。 在技术层面上的定义是:将采集的声音信号经过压缩与封包以后,以数据封包的形式在ip网络进行语音信息的传输。

实现流程 当用户上网后,使用我们的网络电话产品,通过采集用户的麦克风和声卡的数字信号进行压缩与封包处理,然后通过网络传输, 将数字封包传输到离目的地最近的电话网关, 然后通过电话网关将数据信号转化成在公告电话网上传输的模拟信号,并拨打对方的电话, 这样双方就可以通过互联网进行通话。

直拨与回拨 直拨:整个过程都必须依赖网络,因为整个过程都是走的网络流量,过程就是将用户的语音信号,在直拨系统中进行传输给锁拨打的用户

回拨:只有在发起通话时需要网络,因为客户端样发起回拨请求后,一旦回拨系统接受请求就不再消耗用户的流量。

客户端发起回拨请求,回拨平台接受到请求后,先返回一个回拨成功码,用于客户端处理流程, 同时回拨平台会以运营上的身份回拨给呼叫方,呼叫方在听到响铃后选择接听,第一条通话链接就建立好了, 然后回拨平台呼叫被叫号码,被叫方在听到响铃后选择接听,第二条通话链接建立完成,然后回拨平台把两条线路搭通,双方就可以通话。

回拨会根据被叫方的话单进行扣费,通过流程知道回拨会有2次落地,所以回拨资费基本是直拨资费的2被,因为回拨接通后,不依赖网络,所以回拨的 的通话质量会优于直拨通话。

技术相关概念

封包: 将一定时长的数字化之后的语音信号组合为一帧,然后按照国际电联标准,将这个语音信号帧封装到一个RTP(实时传输协议)报文,在进一步封装到UDP报文和IP报文中 电话网关: 普通电话能够通过网络进行通话的电子设备,它是可以将internet和公共电话网(PSTN)连接在一起的系统,一段连接internet,一端是可以 打进打出的电话系统。

落地:在电话网络中。信号传输给公共电话网(运营商的网络),然后通过运营商的线路路由拨打到用户所拨打的手机上, 运营商按照落地的次数收费,我们按照通话时间收费。

  1. 自我介绍 答案:您好,我叫段艳妮,陕西武功人,2010年7月毕业于西安工程大学计算机系的计算机科学与技术专业。 从事IOS开发6年时间,2011年10月到2012年3月在深圳市蜂巢资讯传播有限公司从事ipad杂志开发,期间参与外滩画报,嘉人的开发工作, 2012年4月到2015年10年在深圳市果岭电讯有限公司从事iphone客户端开发,期间参与的项目主要是kc网络电话,在后期担任IOS客户端组长,负责关键技术专研和客户端工作协调。曾独立完成编写socket通信的客户端,与后台使用socket建立tcp长连接,替代以往http连接,加快客户端的响应速度。 2015年11月到2016年12月在深圳市和中易有限公司从事iphone客户端开发,独立完成项目淘心和51结婚。

2.谈谈你的51结婚这个项目吧 1

您好,51结婚是一款高端实名认证的婚恋交友产品。整个项目分为四个模块:登录注册,首页,消息,我的主页。首页主要是展示我们推荐的优质用户,会着重表明用户的四大认证结果,二级页面展示用户的详细信息,可与之打电话,聊天,互相心动。消息,展示的用户间的心动记录,来访记录和消息记录。我的主页主要包括个人信息展示和修改,常用设置,商城三大功能。商城提供用户购买VIP卡和畅聊卡的功能,支持微信,支付宝,苹果支付三种支付方式。这个项目是我独立开发的,我的主要工作是:项目需求分析,客户端架构设计和编码实现,产品交付及后期产品维护。在开发中我善于与产品沟通,充分理解产品的需求,善于与UI沟通,确保产品的效果的高度还原。具有极强则责任心,能积极主动完成开发工作,确保项目的按时保质完成。

======================= 项目技术点

网络电话 1.建立socket长链接。提高网络请求速度 2.ping地址,为用户选择最优的服务器 3.通讯录操作及管理,及通话记录本地管理 4.苹果应用内支付, 5,做组长后,组织和推荐项目重构,重新搭建项目框架 6.与后台配合做应用内广告, 7.接入第三方sdk,数据统计,分享,

淘心/51结婚: 1.环信即时语音和视频聊天,及实实计费, 计费原理: socket长链,报告后台这种通话状态,想要后台20秒一次的心跳来检测客户端是否在通话中,通话结束断开socket链接 2.微信支付和支付宝支付 3.讯飞语音听写 4.UItableviewcell的自定义和复用 5.图片的缓存和异步加载sDWebview,图片裁剪

//项目技术点: ipad杂志 1.scrollview4页缓存机制 2.利用kvc加分类实现的页面完全有后台定制,并支持随时更换

scrollview4页缓存机制 1.需要1个字典,这个字典中存放三个页面,分别是左侧页面,当前页面,右侧页面, 2,需要一个复用对象 3.初始化是复用对象为空,直接创建三个对象,代表左,中,右三个页面, 当用户在当前页面右滑时,左侧页面就可以取出作用复用对象, 当用户在当前页面左滑时,右侧页面就可以取出作为复用对象 4.创建对象的过程,先检查是否存在复用对象,若存在,则将复用对象数据清空即可食用 若无复用对象,则自己创建对象使用。 三个页面加一个复用页面,所以叫四页缓存。

2,页面后台定制 1.所有页面对象都UIView,UIVIewcontroller及这个属性都是NSObject的子类 2.NSObject支持kvc。即setvalue forkey 3.oc 的runtime动态运行机制决定。在运行时会根据指针对象的具体对象来调用子类的方法,所有只要给这个view 和viewcontroller 添加一个setvalue forkey的分类就可以实现属性的动态添加 4.而后台的json文件就已经决定了页面的次序,addsubview 即可。 最后根据类命返回一个view或者viewcontroller即可完成页面动态化加载

遇到什么bug? 1.kc网络电话的时候有一版我们添加了多人会议的功能。当时有一个bug就是只要已进行多人会议就会崩溃,用户的配置信息。自定义结构体。 这种问题我们一般都是,先打开僵尸变量。然后一步步缩小页面。在页面上在屏蔽部分功能。也就是让那些功能什么也不做。直到定位到每一个函数,然后就一步步一行行代码调试,看看到底在哪一行,找到后。 职责: 1.根据软件设计规范,开发基于iOS的应用程序 2.针对开发中的问题提出解决的方案 3.负责基本框架的搭建及项目的完善。 5.负责重点功能的攻克,编写技术文档,与UI,产品,后台进行沟通,共同完成项目

业绩: 高效率的完成每一部开发工作,受到领导的高度好评!

缺点:比较注重产品的质量,如果出现页面卡顿或者说是UI效果有出入,我会不自觉去做一些修改和优化,甚至和UI进行讨论,来确定到底是什么效果比较好,对于页面卡顿的,一定会尽量找出原因,会在没有交给测试部测试前解决问题,尽量保证自己的产品在测试部一次通过。

自动化测试。脚本语言,UITesting

###程序性能优化: 分四个方面考虑:数据处理,UI处理,内存处理,程序响应速度

####1.数据处理:

1)选择正确的存储方式,

2)避免数据的反复处理(处理好的数据用健值对保存)

####2.UI处理:

1)优化talbeview

2)正确设置背景图片

3)imageView 的image 需要先处理成大小和imageview一致

4)利用opaque属性

5)避免庞大xib,尽量使用storyboard

6)合理使用复用标记

####3.内存处理

1)使用ARC

2)处理内存警告

3)使用autoreleasepool

4)使用懒加载

5)使用缓存

6)重用大的开销对象(NsDataFormatter(时间格式化)等。因为初始化很慢.可设置application的属性)

####4.响应速度

1)加速程序启动(尽量缩短启动时间,只在主线程做一些必须的设置和页面加载,其他的都放到子线程中进行)

2)只在处线程处理UI刷新,能放到子线程的就一定放到子线程中进行。

###优化tableview

1)正确使用cell复用
2)缓存行高
3)减少subviews数量,及自定义cell,提高渲染效率
4)图片等异步加载,避免堵塞
5)如果行高固定,使用属性rowHight设置,而不是delegate的hightForRow。
    同理footHight,HeadHight

tableview 的流畅度的如何提升?

1.每次都检查有无重用cell,尽量不重新创建cell

2.cell 里尽量使用drawRect画而不使用UIView

3.图片载入放入后台进程 4.cell数据尽量提前缓存好,不读现用现去读文件

5.数据量大的尽量做一个load more cell 出来,避免边滚边读

###正确设置背景图片

1.纯色背景直接使用backgroundcolor
2.如果时那种规则的小格子组成的背景图。使用UIColor的ColorWithPatternImage来处理,会花费更小的内存
3.不是1.2.就使用addsubview ,添加一个UIImageView做背景图片

###对于不透明的view将opaque必须设为YES, 因为opaque是一个性能优化开关,设为YES可以提高渲染系统的性能,一般View此值默认为YES,但UIButton,UIlabel等默认为NO,需特别注意

###尽量避免庞大的xib, 可以考虑使用storyboard,因为后者只在需要的时候实例化viewcontroller

触摸事件处理机制

###概念

触摸事件处理机制即界面响应消息机制

###步骤 界面响应消息机制分两步处理

(1)寻找响应消息视图:即在视图的层次结构里找到能响应消息的那个视图。

(2)消息处理:即在找到的视图里调用touches方法处理消息。

touches方法默认的做法是将事件顺着响应者链条向上传递,即将事件交给上一个响应者进行处理

###注意事项

寻找响应消息视图的过程是从父View到子View查找,而消息处理是从找到的那个子View往父View回溯(如果子视图处理则不会继续往回传递消息)。

###寻找响应消息视图的过程

####处理原理 1.当用户点击屏幕时,会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中

2.UIApplication通过事件分发将事件发送给应用程序的主窗口(UIWindow)

3.主窗口会调用hitTest:withEvent:方法在自身的视图(UIView)层次结构中找到一个最合适的UIView来处理触摸事件

window的.hitTest:withEvent:处理流程:

从window的跟视图开始,首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内:

▶若pointInside:withEvent:方法返回NO,说明触摸点不在当前视图内,则当前视图的hitTest:withEvent:返回nil,此分枝便利结束

▶若pointInside:withEvent:方法返回YES,说明触摸点在当前视图内,则遍历当前视图的所有子视图(subviews),调用子视图的hitTest:withEvent:方法重复前面的步骤,直到所有子视图的hitTest:withEvent:方法遍历完毕.

注意:视图的hitTest返回非空,那这个视图就将成为响应者链上的一员。

####举例说明

这里ViewA包含ViewB和ViewC,ViewC中继续包含ViewD和ViewE。假设我们点击了viewE区域,则hit-test View判定过程如下:

   1. 触摸在A内部,所以需要检查B和C
   2. 触摸不在B内部,在C内部,所以需要检查D和E
   3. 触摸不在D内部,但在E内部,由于E已经是叶子了,所以判定到此结束,A视图的hitTest:withEvent:返回视图E,就是视图的第一响应者。

消息处理过程,

在找到的那个视图里处理,处理完后根据需要,利用响应链nextResponder可将消息往下一个响应者传递。

###响应者链条:

响应者链条是由多个响应者对象连接起来的链条。

###响应者对象:

继承与UIResponder的能处理事件的对象。

###响应者链条是如何形成的呢?

在寻找相应视图的hit-testing过程中我们知道事件的传递顺序是这样的: ->UIApplication对象

->UIWindow

->UIWindow的subviews中更合适的view1

->view1的subvies中更更合适的view2

...

->....最合适的view

这样就组成了一条事件响应者的链条,从最合适的view 开始,一路往上一直到applicaiton对象结束。

###应者链条的事件传递过程:

从链条的末端视图view开始,

》如果view处理了就结束传递,

》如果view未处理就继续向上传递给上一个响应者(比如view2),

然后沿着这个响应者链条一直向上传递,直到传递给window对象,如果window对象也不处理,就传递给Application对象,如果Application也不能处理该事件或消息,则将该事件丢弃

###总结:

1、iOS寻找响应消息视图是从View层级结构的父View向子View传递,即树状结构的根节点向叶子节点递归传递。

2、找响应消息视图过程中的hitTest和pointInside成对,且hitTest会调用pointInside。

3、iOS的消息处理是,当消息被视图处理后默认不再向父层传递。

###其他小问题

用户触屏事件是如何进入application的事件队列中的?

用户触屏,硬件报告触摸事件给UIKit框架,UIKit框架将事件打包成UIEvent对象,并加入application的事件队列中。

####UIWindow为何可以调用hitTest:withEvent方法

hitTest:withEvent:是UIView的一个方法,UIWindow继承自UIView,故可以调用此方法

hitTest:withEvent返回视图规则:

  1. 如果某视图的pointInside:withEvent:返回YES,但他的所有子视图hitTest:withEvent:都返回nil,则返回自己。

2.如果某视图的pointInside:withEvent:返回YES,而且该视图已经是叶子视图(即它没有子视图),那么返回自己。

####hitTest:withEvent:方法会忽略的视图有那些?

1.隐藏(hidden=YES)的视图, 2.禁止用户操作(userInteractionEnabled=NO)的视图, 2.alpha级别小于0.01(alpha<0.01)的视图。

####超出父视图的子视图如果能看见,那它会响应事件吗?如何处理

子视图超出父视图的显示区域bounds,若父视图的clipsToBounds为NO,则子视图超出部分会被裁剪不会被裁剪,但是子视图超出的部分是不会响应事件的,

这是因为父视图的point insert在自己的bounds 之外返回了NO。非要相应事件那就自己重写父视图pointInset方法,则bounds之外返回YES即可。

####传递给上一个响应者的规则是(也就是如何判断上一个响应者):

1)如果当前视图是控制器的跟视图,那控制器就是下一响应者,

2)如果当前视图不是控制器的跟视图,那它的父视图就是下一响应者

####事件的传递和响应的区别:

事件的传递是从上到下(父控件到子控件),

事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件

####如何拦截事件处理?

重写需要处理事件的视图的hitTest:withEvent方法,返回某个视图作为最合适的视图

####如何做到一个事件多个对象处理:


重写自己的touches方法,自己处理完成后再调用[super touches]就把事件处理传递给了父视图。如果需要继续上传,父视图这样按照子视图这样处理一下。

一些基本概念

###UIKit的基本概念继承关系图

IOS所用在界面上显示的对象都是直接或者间接继承与UIResponder

###几个基本概念

####应用程序(UIApplication)

一个UIApplication对象代表一个应用程序,程序启动后创建的第一个对象,而且是单例,获取该对象方法为[UIApplication sharedApplication]

####视图(UIView)

UIView的实例就是视图,负责在屏幕上定义一个矩形区域,同时处理该区域的绘制和触屏事件,视图可以嵌套,也可以叠加,像UIImageView等都是UIView的子类,UIbutton是UIView下UIControl的子类,也是视图

####窗口(UIWindow)

UIWindow管理和协调应用程序的显示,继承与UIView

是程序启动完毕后创建的第一个视图控件。

一般情况下,应用程序只有一个UIWindow对象,即使有多个,在同一时刻也只有一个可以接受到用户的触屏事件

####视图控制器(UIViewController)

视图控制器管理UIVew实例的生命周期和资源的加载与释放,

处理设备旋转导致的屏幕旋转,

与构建复杂用户界面的高级导航navigationcontroller,tabbarcontroller等对象进行交互

####容器(Container) 一个app可能有很多的UIViewContrller组成,这时需要一个容器对这些UIViewController进行管理,

大部分的容器也是一个UIViewController,比如UInavigationController,UItabbarController ,

有的不是UIViewController,如UIPopoverController(继续NSObject)

总结:容器就是用来管理app的视图控制器(UIViewController)的对象。

###UIView、UIWindow、UIScreen、UIViewController 之间的层级关系

###UIWindow和UIView的关系:

二者之间的关系可以想象为一个场景;首先有一个空的画框(UIWindow),我们在画框上放置一块画布(UIView),然后就可以在画布上进行绘画,画布上可以画上各种元素,如UIlabel,UIbutton等,这些元素也可以看作是一个又一个的小画布(UIView),他们之间会有一个层级关系管理,可以理解为ps中的图层,层级高的元素会覆盖层级低的元素,从而导致层级低的元素被部分或者完全遮挡。

###UIApplication可进行应用级别的操作有

####设置应用图标右上角的红色提醒数字

    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:3];

####设置联网指示器的可见性

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

####管理状态栏

[[UIApplication sharedApplication] setStatusBarHidden:YES 
                                withAnimation:UIStatusBarAni  mationFade];

####发信息

 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://10010"]];

####打电话

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10010"]];

####发邮件

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://jinnchang@126.com"]];

####打开一个网页

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://blog.csdn.net/jinnchang"]];

####跳转到 AppStore

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https

###UIWindow相关:

####UIWindow在程序中主要起到三个作用:

1、作为容器,包含app所要显示的所有视图

2、传递触摸消息到程序中view和其他对象

3、与UIViewController协同工作,方便完成设备方向旋转的支持

####设置window为主窗口并显示出来

    [self.window makeKeyAndVisible];

####WindowLevel

UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面,三个level的高低顺序从小到大为Normal < StatusBar < Alert

####特殊性

UIWindow是一种特殊的视图,没有相应的视图控制器,但一般的UIView都有相应的视图控制器。

###UIkit的坐标与core Graphics或者OPebGL坐标区别

UIkit的坐标原点是左上角,向右为x轴

core Graphics和OPenGL ES 的坐标系统的原点在左下角,也是向右为x轴

###视图(UIView)操作注意事项:

1)最小化定制的绘画(少写少调用DrawRect)

3)使用内容模式:(contentMode)但不用UIViewContentModeReDraw

4)尽量Opaque设为YES来优化绘制操作

5)使用已经存在的视图来定制视图,多使用组合少继承

6)不要在滚动时改变视图的行为,因为会导致视图在短时间内更新,对绘画效率要求很高,很耗费资源,建议不要总是保证视图内容。而是采用滚动操作开始时改变视图的行为,当视图滚动停止时,你可以将视图返回到前一状态,同时更新需要更新的内容。

###使用DrawRect有什么坏处 在有touch event 的时候会,系统会强制使用setNeedsDisplay重绘,

会导致drawRect被重复调用,而且每次单机事件会触发2次

所有在比较多的UIButton的页面会比较耗内存和cup

###调用drawrect时机

1.初始化是为设置frame时,drawrect不会自动调用

2.调用在loadview andviewDidLoad之后调用

3.sizetoFit会调用

4.sitNeedDisplay会调用

5.contentmode为redraw则每次改变frame均会调用

###drawRecr调用原理:

在每一次使用SetNeedsDisplay并不会立即重绘,

而只是将此图层layer 标记为dirty(脏的),然后什么也不做,

直到等到下一次渲染视图周期,才会将标记为dirty的layer重绘,

即重新建立Core graphic 上下文,并从内存中恢复数据。

再使用core contextRef绘制。

###调用layoutsubview时机

1.frame发生改变,会调用自身和父视图的layoutsubview。

2.andsubview

3.滚动

4.屏幕旋转

App和UIViewController的生命周期

####main.m文件

@autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));}

####UIApplicationMain 详解

UIApplicationMain(argc, argbv,  nil, nil)

参数一:不管

参数二:不管

参数三:代表UIApplication对象,默认用缺省值创建和初始化

参数四:代表UIApplication对象类

###UIApplicationMain函数的作用:

1.创建app核心对象,UIApplication,通过调用[UIApplication sharedApplication]来得到这个单例实例的指针

2.指定UIApplication的delegate

3.从storeboard加载用户界面

4.自动启动Main RunLoop.并为其创建一个autoreleasepool

###UIApplication作用 1.UIApplication的一个主要工作是处理用户事件,它会创建一个队列,把所有用户事件都放入队列,逐个处理,在处理的时候,它会发送当前事件到一个合适的处理事件的目标控件。

2.维护一个在本应用中打开的window列表(UIWindow实例),这样它就可以接触应用中的任何一个UIView对象。

3.UIApplication实例会被赋予一个理对象,以处理应用程序的生命周期事件(比如程序启动和 关闭)、系统事件(比如来电、记事项警告)等等

###UIApplication与其代理类(AppDelegate)之间的关系 UIApplication 是管理整个程序的生命周期,但他什么具体的事情都不做,他只是负责监听事件当需要真正做事情的时候就交给其代理类(AppDelegate)去做。

它做的是在后面维护一些App不可更改的东西,比如:事件消息的分发和传递,给委托AppDelegate发送系统从事件处理请求。

UIAppDelegate和其代理类AppDelegate存在一些已定义的协议接口,用于处理系统事件

注意:UIApplication对于用户输入事件是传递给相应的目标对象去处理。

###App的关键对象关系图

整理是MVC模型架构,好处:使数据的展示视图(View)与数据(Model)和业务逻辑(controller)划分开来,也就是说视图和数据及业务逻辑无关,方便创建统配app

###应用程序生命周期图

如果要按下home,需要程序直接退出可以在Plist中设置

Application does not run in backgroud 为YES或者私有api [application termianteWillSuccess]

(会导致无法上架appstore))

####应用程序生命状态名词解释

Not running 未运行,即程序没启动

Inactive 未激活,即程序在前台运行,不过没有接收到事件。

Active 激活,即程序在前台运行而且接收到了事件。

Backgroud 后台,即程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态

Suspended 挂起,即程序在后台不能执行代码。但程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。

##UIViewController生命周期

1.init/ initwithNibname。默认xib文件名就与类名相同

2.Loadview:每次访问UIViewController的跟视图为nil时会自动调用此方法,开发者可以进一步定制view。

3.viewDIdLoad

注意:UIviewController必须重写viewDIdLoad,且需调用[super viewDIdLoad]

4.viewWillAppear:(BOOL)animated;

5.viewDidAppear:(BOOL)animated;

6.viewWillDisappear:(BOOL)animated;   7.viewDidDisappear:(BOOL)animated;   8.didReceiveMemoryWarning内存吃紧时调用 9.dealloc ()

###didReceiveMemoryWarning的实现 默认实现:ios6.0之前会释放UIviewContrller的resource和view ios6.0之后只会释放UIviewcontroller的resource

释放view指的是:如果当前ViewController的view没有显示在window上,会自动将viewcontroller 的view以及其所有子view全部销毁,然后调用viewcontroller的viewdidunload方法)

  -(void)didReceiveMemoryWarning{

    [super didReceiveMemoryWarning];

    if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0) {
    // 是否是正在使用的视图
    if (self.isViewLoaded && !self.view.window)
  { 
   self.view = nil;// 目的是再次进入时能够重新加载调用viewDidLoad函数。
   }
     } }

即使没有显示在window上,也不会自动的将self.view释放

用self.isViewLoaded判断视图是否正在使用,其他方式访问视图会导致即使不在使用视图的加载

###dealloc调用时机

释放一个viewcontroller的成员和它自身的东西,是viewcontroller的生命结束点。在UIViewContorller的RC = 0自动调用

注意事项:ARC下不可调用[super dealloc], 而且只可以释放资源(非view的东西)

###UIViewController创建view的loadview具体实现

loadview默认实现:即[super loadView]的实现

1.查找与UIViewController相关联xib的文件,通过加载xib来创建UIviewcontroller的view

2)如果没有找到这个xib文件,就自动创建一个空白的view赋值给UIviewController的view属性

###如何通过代码来自定义UIViewController的view?

重写laodView,但是不调用[super loadView],而是自己用代码创建一个view赋值给UIviewController的view属性

####目标 是动作消息的接收者。可以是一个控件,或插座变量,如UIButton

####动作: 从目标的角度看,动作是目标为了响应动作而实现的方法。 从控件的角度看,动作是控件发送给目标的消息,

delegate与 Notification区别和使用时机?

delegate

针对one-to-one关系,它有一个协议链,并且代理对象可以返回值 给调用代理方法的实例。

notification

可以针对one-to-one/many/none 发通知者仅负责发布通。无法接受监听者的任何返回数据,

区别

需要返回某些数据给定义协议链的对象时使用delegate,其他情况使用代理和notification是一个作用。

###代理

代理,又称委托代理(delegate)

产生原因

事件是对象发送的消息,以发信号的方式通知操作的发生。但是存在事件的发送方无法知道事件的接收方的情况

目的

是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。

换句话说:是给一个对象提供机会对另一个对象的变化做出反应。基本思想是两个对象协同解决问题

作用

委托协助对象主体完成某项操作,将需要的定制化的操作通过委托对象来自定义实现,达到和子类化主体对象相同的作用

事件监听。委托对象监听主体对象的某些主要事件,对事件作出具体响应或广播事件交给需要作出响应的对象。

好处

避免了子类化带来的过多的子类就是雷爆炸和子类与父类的紧耦合

通过委托传递消息机制实现分层解耦

###协议 概念

协议声明了一组可以供任何类实现的方法,协议本身不是类,它只是简单的定义了一个其他对象可以实现的接口集合。

@optional表示可选的协议方法;@required表示必须实现的协议方法

注意:协议没有实例变量或父类只有接口

实现协议(做了其他类的代理)

实现其他类的协议方法就是做了其他类的代理, 也就是做了其他对象的委托对象

    比如:A实现协议C,B调用协议C。那么B就是被委托者,A是B的委托对象。

添加协议:

定义需要其他类实现的方法叫做添加协议。实现其他类的协议方法就是做了其他类的代理,

添加代理

就是指明自己定义协议类让谁实现

###ios消息传递方式

1.通知:

在ios中有消息中心进行消息接收和消息广播,是一种一对多的消息传递方式

2.代理

是一种通用的设计模式,用于代理者和被代理者协调解决问题。在ios中有代理对象,委托者,协议三部分组成,让被代理者在何时的时候通过协议调用代理者实现的方法。

3.block

ios中的一种回调方法,可以将回调处理代码直接写到block代码块中,好处是逻辑清晰,代码整齐。

4.target action

button和viewcontroller的交互方式,在视图控制器中添加xib文件的buttong的action就可以事件button的事件传递,

5.kvo

是NSObject的分类——NSKeyValueObserving,通过监听对象属性值的变化,当属性变化时回调kvo的回调方法

##网络发送数据流程图

##网络七层各层名称和作用

应用层:主要是终端的应用,比如FTP(文件下载),qq。浏览器

表示层:主要对接受的数据进行解释,压缩和解压缩,即把计算机识别的东西(1.0)转化为用户设备的东西(图片.文字)

会话层:通过传输层建立数据传输通路,在设置之间进行发起会话或者接受会话的请求,就是说它是对传输层的管理,用于建立.维护。管理连接

传输层:定义了传输数据的协议和端口,如tcp/udp。主要将从网络层接受的数据进行分段和传输,这一层的数据叫做段

网络层:从数据连接层接受的数据进行ip地址的封装和解封装,称作ip协议,这一层数据叫做数据包。作用网间寻址

数据连接层:从物理层接受地址进行MAC地址封装和解封装

物理层:定义物理设备标准, 作用是传输比特流

##网络OSI七层和TCP四层结构图对比

tcp协议    对应于传输层  
 ip协议     对应于网络层
TCP/IP是传输层协议,主要解决数据如何在网络中传输;
而HTTP是应用层协议,主要解决如何包装数据。

###TCP的三次握手建立连接

第一次握手:Client端发送连接请求报文(syn包),进入SYN_SEND状态等待服务器确认

第二次握手:Server端接受连接后回复ACK报文,并为这次连接分配资源

第三次握手:client收到ACK报文后,向服务器发送ACK确认包,并为这次连接分配资源,至此完成三次握手,这样TCP连接就建立了

注意:握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去

###TCP的四次挥手断开链接 注意:中断连接可以由Client端发起,也可以由Server端发起 以客户端中断连接为例:

第一次握手:Client端发起中断连接请求(即发送FIN报文)

第二次握手:Server端接到FIN报文,先发送ACK,客户端进入FIN_WAIT状态,等待Server端的FIN报文

第三次握手:当Server端确定数据已发送完成,则向Client端发送FIN报文

第四次握手:客户端受到FIN报文后,发送ACK报文。进入TIME_WAIT状态。等待30秒左右,没有收到服务端的任何数据,证明服务端已正常关闭,然后客户端就会关闭tcp连接

###为什么TCP连接的时候是三次握手,关闭的时候却是四次握手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

###为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

###HTTP协议概念: 超文本传送协议,是应用层的协义,是建立在tcp数据传输协议的基础上实现的。

http协议规定,在用户发送请求前,必须先通过tcp建立三次握手建立连接,

使用的是“请求—响应”的方式,即客户端发送请求,服务器响应,然后链接立即断开。俗称短连接

###http链接特点: ·每次请求前均需要通过tcp三次握手建立链接 ·只有客户端发出请求后服务器才能响应 ·服务器响应请求后会立即断开,同时客户端在请求结束后会自动释放链接

###TCP与UDP

TCP:传输控制协议 ,是可靠协议,会建立连接,形成数据传输通道,而且数据传输无大小限制,确保数据安全送达,但效率比较低。

UDP:用户数据包协议,是不可靠的协议,无需建立连接,只是将数据源和目的地封装为一个数据包来进行发送,大小必须在64k之内。无法保证对方收到数据,但速度快,效率高

UDP实际应用:电脑共享。发送短信,

###UDP如何实现可靠传输

udp是无连接的,是不可靠协议,它不管是否丢包,也不保证传递顺序。

所以如果要求数据发送和接受即要高效,又要保证有序,收报确认等,需要在UDP协议上 构建自己的协议,

比如添加收包确认,添加收发序列号,拥塞控制,丢包重发机制,比如实时传输协议RTP协议就是对UDP的改进。

###socket概念

Socket又称之为“套接字,本身并不是协议,是对TCP/IP协议的封装,

是系统提供给程序员用于发送和接收消息的接口,

在socket通信中需要通信2两端都是socket,分别叫ClientSocket和ServerSocket,数据在socket两端通过IO传输。

####Socket指定协议

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或 UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接

###Socket连接过程

服务器监听

客户端请求

连接确认

服务器监听:指服务器端绑定(bind)端口并处于等待连接的状态,实时监控(listen)网络状态,等待客户端的连接请求。

客户端请求:指客户端的套接字发出连接请求(coonect),要连接的目标是服务器端的套接字。并在连接中指出服务器端套接字的地址和端口号。

连接确认:当服务器接收到客户端连接请求时(accept),就响应客户端套的链接请求。

###服务器短如何响应客户端的socket连接请求?

首先建立一个新的线程,然后把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。服务端采用一个数组来保存所有客户端的套接字信息

###为什么出现socket。什么时候socket?为什么http不够用?

HTTP连接使用的是“请求—响应”的方式,是短链接,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据

Socket使用场景:

如果需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步, 若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端。 因此,socket链接,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

###socket断开

如果是客户端主动关闭,会先发送关闭消息给服务器,然后关闭客户短,服务器接收到关闭消息后会自动断开连接

如果是服务器断开连接,则是服务器发送关闭消息,客户端接受到主动断开连接

比如客户端发送三次心跳都收不到服务器的响应,可以认为是网络不好,客户端主动断开连接,发送关闭消息,是第一种情况。当然也可以重新连接,

###socket即时通信 从图中我们知道

1.服务器和客户端通过socket建立tcp长链接后,两端就各有一个输入流和输出流, 其中输入流,会一直监听者输入流,看有没有数据到来

2.服务器的作用是做一个数据的中转

###socket包含进行网络通信必须的五种信息:

·连接使用的传输层协议

·本地主机机IP

本地进程端口

远地主机IP

远地进程端口

###TCP长连接和短链接

tcp短链接:指client向server发起连接请求,server接到请求,然后双方建立连接。然后client向server发送消息,server回应client,这样一次读写就完成了,这时候双方任何一个都可以发起close操作,一般是客户端发器close消息,servier收到会直接关闭连接。

Tcp长链接:指client向server发起连接,server接受client连接,双方建立连接。然后客户端和服务器直接传递消息,完成一次读写。但是完成一次读写后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接

###Tcp长连接何时关闭连接? 在tcp长连接的情况下client端一般不会主动关闭它们之间的连接,但是为了防止客户端越来越多导致服务器崩溃,服务器会采用一些策略来关闭连接。比如

关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损,

或者限制每个客户端的最大长连接数

###http和socket的区别 分四个方面描述:概念,长短连接,数据传输模式,数据传输格式

####概念

HTTP协议:超文本传输协议,是应用层协议,主要解决如何包装数据。是基于TCP连接实现的。

socket:又称为“套接字,本身并不是协议,是对TCP/IP协议的封装,是系统提供给程序员用于发送和接收消息的接口.

在socket通信中需要通信2两端都是socket,分别叫ClientSocket和ServerSocket,数据在socket两端通过IO传输。

####长短连接

http连接就是所谓的短连接,即客户端每向服务器端发送一次请求,服务器端响应后连接即会断掉.

socket连接就是所谓的长连接,是由于通常情况下Socket连接采用tcp协议,而且Socket连接一旦建立,将不会主动断掉,通信双方开始相互发送数据内容,直到有一方主动断开连接

####数据传输模式

http连接是“请求-响应”模式,只能客户端发器请求,建立连接,客服端发送请求信息,服务器响应,断开链接,

socket链接是,一旦客户端和服务器建立连接,则可互发消息,只到其中一方主动断开连接

####数据格式

http传输的格式是规定好的 ,有请求头,请求体,响应头等

socket实现的数据传输是原始的输入输出数据流。

###socket的实现方式: 1。OC的输入输出流NSInputStream,NSoutputStream和C语言CFStream相结合来实现主要用于即时通讯,是阻塞是的socket

2.GCDAsyncSocket 异步socket,是基于C语言实现。不会阻塞当前线程

实现原理:首先使用GCD创建异步子线程,在子线程中建立c语言级别的socket连接,建立c语言的输入输出流,并分别设置读写回调,连接成功或者读写数据完成都会返回主线程,然后通过外部接口返回数据

缺点:每次发送数据后都需要客户端主动读取数据,否则获取不到服务器的返回

3.BSDsocket 是纯c语言的socket ,分别阻塞和非阻塞2中,通过在链接是设置来决定是否阻塞,

我使用过的是阻塞模式的socket,这样的socket会阻塞当前线程,所以采用的是建立两个子线程处理数据读写,并通过线程锁来保证数据同步,客户端通过发送心跳来维持跟服务器的连接,三次心跳无返回则会任务服务器异常,主动断开连接,closesocket。

###bsd socket如何处理阻塞问题: 连接前设为非阻塞模式,连接成功后,设置为阻塞模式

###socket为什么会有粘包? 粘包,指发送方发送的若干包数据在接收方接收到的是粘在一起的一包,也就是后一包数据的头紧接着前一包数据的尾。 出现粘包既可能由发送方造成,也可能由接收方造成。

1.发送方引起的粘包是由TCP协议本身造成的.

TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP 会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

2.接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象

因为接收方需要先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据, 若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到前一包数据之 后,等用户从缓存区获取数据是就一次取到了多包数据。

###socket如何处理粘包问题:也就是如何分包 分包:是指在出现粘包的时候我们的接收方要进行分包处理。

1.通过包头+包长+包体的协议形式,当客户端获取到指定的包长时才说明获取完整。

2.指定包的结束标识,这样当我们获取到指定的标识时,说明包获取完整。

###socket数据包头作用: 通过数据的包头格式,知道数据的长度和种类来处理各种业务类型

###可能导致socket是连接断开的原因有哪些 1.服务器端或客户端主机down了, 2.网络故障, 3.或者两者之间长时间没有数据传输, 4.网络防火墙可能会断开该连接以释放网络资源。

###tcp协议和ip协议 tcp协议:是传输层协议,解决数据的分段和传输,ip协议:网络层协议,解决数据的网间寻址。

###socket的好处是: 也就是服务器可以向客户端通信消息,用于维持客户端和服务器的数据同步。

###IO:就是输入输出流,

I:输入流:用于读取数据,即读取从另一个socket获得的数据。

O输出流:用于写数据,即发送数据给另一个socket

###设备之间如何互相认识 通过端口号和ip地址就可以唯一确定一台设备,从而让设备之间互相认识

###端口

用于标示进程的逻辑地址,电脑的每一个应用都以一个端口

###IP地址

唯一标示网络设备的,与域名一一对应

本机地址:127.0.0.1 域名 loaclhost

###访问域名的流程

如www.baidu.com(域名) ->首先通过DNS服务器转化为百度的ip地址,然后通过这个ip地址访问百度服务器,

DSN:域名解析器,将域名解析为IP地址

###传输协议

用什么样式进行交互,即通信规则,常见协议TCP,UDP

###TCP与HTTP TCP:是传输方式

HTTP:是一种数据格式,

举例说明: 从广东到北京,可以火车,飞机(tcp),到北京后,进行交流,用英语,国语(HTTP)

###手机可以可以使用联网功能的原因是?

因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。

###简单聊天室(socket) 即socket即时通讯的实现: 方式一:使用OC的输入输出流和C语言socket相结合来实现 > 关键类:CFStream NSInputStream NSoutputStream

1.开启服务器

2.客户端1.建立连接,分为5小步

1)与服务器完成三次握手建立连接,并为输入输出(CGReadStreamRef)流分配内存,通过c语言的:CFStreamCreat PairWithSocket实现

2)c语言的输入输出 通过桥接转为oc的输入输出流NSOutputStream

3.输入输出流设置代理

4)把输入输出流加入主线程的runloop(因为只有在主线程的事件循环中才能才能检测网络变化

5)打开输入输出流

3.完成输入输出流的回调函数 stream:handleEvent

根据事件类型分别处理各种流事件,并完成登录事件

OpenCompleted:输入流或者输出流打开完成,可以理解为socket连接完成
HasBytesAvailable:输入流有事件,可以进行读取,解析服务器的返回信息
HasSpaceAvailable:输出流准备ok,可以发送数据,发送登录指令
endEncoutered:连接断开,需要关闭输入输出流 并在runloop中移除输入输出流

4.发送消息,解析消息

    发送数据 [ outputStream write]

消息和登录指令都是数据,区别仅仅只是格式不同,服务器接收到数据后只是进行数据转发

5.读取数据 [inoutStread read]

方式二.使用xmpp协议实现

git上有开源的xmpp框架,我们需要做的就是更具整个框架提供的接口实现,登录注册等功能。

###http的post和get啥区别?

请求方式:

get主要用于从服务器获取数据,参数部分是直接跟在?之后,相当于是明文的,不是很安全

post主要用于向服务器发送数据,参数部分可以加密传递给请求的body部分,相对于get来说数据比较安全。

大小:

get的长度有限制大概是1024.

post就没有限制

对服务器而言:

get不会修改服务器上的数据,

post却可以修改服务器上的数据,

当在现实中我们都是使用post,因为受到请求知道处理的都是后台人员。不会出什么问题。

###IM:

即时通讯,Instant Messaging:支持用户现在实时交谈。

比如QQ,MSN,微信,等,区别在于各自通讯协议的实现,也就是说核心在于传输协议的不同。

协议用来说明信息在网络上如何传输,如果有了统一的传输协议,各个im之间可以直接通信 即qq和微信可以直接通信。

###XMPP:

基于xml且开放的可扩展通信和表示协议,即xmpp协议,又称jabber协议

XMPP数据是以XML数据元流式传输,是C/S架构,是客户端通过tcp/ip的方式连接到服务器

xmpp中三个角色:客户端,服务器,网管, 通信可以发生在任何两者之间

基本的网络形式是单个客户端通过tcp /ip连接到单个服务端

###实现类似于微信的即时通讯

注意:微信有自己即时通讯协议,即微信不是xmpp协议

环信即时通讯的协议是仿照xmpp协议,但不是xmpp协议,

xmpp协议在国内应用比较广,因为xmpp已有封装好的开源库,可以节省开发成本。

####xmpp使用: 客户端:连接到openfire ,有开源框架,地址:

https://github.com/robbiehanson/XMPPFramework,需要点击release 下载release版本,如 XMPPFramework-3.6.5

#####XMPPFramework结构 Authentication:授权登录相关

Categories :分类

Core :核心,跟服务器交互的类主要在此文件夹

Extensions:扩展模块,“默认扩展模块的功能都是不工作,比如在此提供了数据缓存模块,但是没有开启”

Utilities(tool)工具类

Vendor:供应商。对于xmpp框架,就是它需要使用的其他第三方框架

- CocoaAsyncSocket: 异步socket
- CocoaLumberjack:第三方日志输出
- KissXML

XMPP的ios框架暂不支持语音和视频,官方文档RFC 3920

###C/S(客户端/服务端),

这种结构必须有客户端app

###B/S(浏览器/服务端) (Brower/service)

##RunLoop http://www.cocoachina.com/ios/20150601/11970.html

###概念

在oc中runloop实际是一个用来管理需要处理的事件和消息的对象。

runloop是一个事件处理的循环,用来不停的调度工作以及处理输入事件, 使用runloop的目的是让线程在有工作的时候忙于工作,而在没工作的时候处于休眠状态

###实现原理:

一个do while死循环,整个循环一直处于“接受消息-》等待-》处理”的过程,直到逻辑结束(比如quit消息)。

###ios的runloop对象

1.core Foundation的CFRunLoopRef。纯c 实现

2.Foundation的NSRunLoop。是oc实现,是面对对象的,是对CFRunLoopRef的封装。

###runloop与线程的关系

1.runloop和线程是一一对应的。 每条线程都有唯一一个和他对应的RunLoop对象,二者是利用字典来存储的,key:线程对象,Value:该线程对应的 Runloop

2.主线程的Runloop系统已自动启动,其他线程的RunLoop需要程序员自己主动启动

3.苹果不允许直接创建RunLoop,只允许获取runloop对象。而且RunLoop的创建是在第一次获取时,在线程结束时销毁,采用的是懒加载的方式加载。

    [NSRunLoop currentRunLoop]//获取当前线程的RunLoop对象
    [NSRunLoop mainRunLoop]//获取主线程的runLoop对象

###获取runloop对象的底层实现?

首先在保存线程和runloop的字典中查找所获取线程的runloop,如果有则直接返回。

如果无则创建一个的runloop,并保存到字典中,然后返回这个runloop。

说明了是runloop的一一对应关系,也说明是懒加载的创建模式,即需要时才创建

###runloop的结构

1.source(事件源) /timer(timer事件)/observer(runloop状态的观察者)统称为一个mode item,简称mode

2.一个runLoop 可以有多个Mode,每一个mode 可包含多个source/timer/observer.

3.每次调用runLoop只能指定一个mode叫为current mode.如需切换 Mode,只能退出当前 Loop,再重新指定一个 Mode 进 入。这样做主要是为了分隔开不同组的 item,让其互不影响

4.如果一个mode中一个item 都没有,则runloop会直接退出。结束循环

###runloop的mode分类

NSDefaultRunLoopMode:app默认,通常用于主线程

UITrackingRunLoopMode:界面跟踪model,用于scrollview

NSRunLoopCommonModes = default+uitracking

UIInitializationRunLoopMode:仅用于app启动

GSEventReceiveRunLoopMode:仅用于接受系统内部事件

kCFRunLoopCommonModes:展位的,用不到

###NSTimer和Runloop

####NSTimer创建方式:

创建的timer不会自动添加到当前线程中

timerWithTimeInterval

创建的timer会自动添加到当前线程的runloop中

 scheduledTimerWithTimeInterval。

###timer 在主线程和在子线程

主线程的mode默认是NSDefaultRunLoopMode,不存在scrollview一切ok

存在scrollview需要指定model 为UITrackingRunLoopMode或者NSRunLoopCommonModes

###timer在子线程

不存在scrollview,加入到子线程的runloop中,需启动runloop

存在scrollview需要:加入到子线程的runloop中,然后指定model 为UITrackingRunLoopMode或者NSRunLoopCommonModes,

###有scrollview切换mode的原因是:

存在scrollview。在点击UIScorllview的区域时,mode是UITrackingRunLoopMode

但定时器的model是NSDefaultRunLoopMode所以定时器会停止工作。

注意:NSRunLoopCommonModes占用模式, 此模式任何时候都会开启定时器

###runLoop的作用:

a 保持程序的持续运行(ios程序为什么能一直活着不会死。applicationmain中启动了一个runloop。 )

b 处理app中的各种事件(比如触摸事件、定时器事件【NSTimer】、selector事件【选择器·performSelector···】. 其他系统事件)

c 节省CPU资源,提高程序性能,有事情就做事情,没事情就休息

###如何让子线程不死?

给这条子线程开启一个Runloop。用于在子线程中接收异步回调。

###主线程Runloop何时创建 在main.m文件中已经创建好了

###Runloop的生命周期

在第一次获取时创建,在线程结束时销毁

###为什么Runloop并不是由系统自动控制的

1.以NSTimer为例,若通过timewithtimeinv创建,需要手动添加到新建NSRunLoop中,而且即使如此也不会自动运行

2主线程默认启动runloop,但子线程不会自动启动线程

故runloop并不是由系统自动控制的.

###runloop的事件处理机制

// 用DefaultMode启动
void CFRunLoopRun(void) {
    CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
}

/// 用指定的Mode启动,允许设置RunLoop超时时间
int CFRunLoopRunInMode(CFStringRef modeName, CFTimeInterval seconds, Boolean stopAfterHandle) {
    return CFRunLoopRunSpecific(CFRunLoopGetCurrent(), modeName, seconds, returnAfterSourceHandled);
}

/// RunLoop的实现
int CFRunLoopRunSpecific(runloop, modeName, seconds, stopAfterHandle) {

    /// 首先根据modeName找到对应mode
    CFRunLoopModeRef currentMode = __CFRunLoopFindMode(runloop, modeName, false);
    /// 如果mode里没有source/timer/observer, 直接返回。
    if (__CFRunLoopModeIsEmpty(currentMode)) return;

    /// 1. 通知 Observers: RunLoop 即将进入 loop。
    __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopEntry);

    /// 内部函数,进入loop
    __CFRunLoopRun(runloop, currentMode, seconds, returnAfterSourceHandled) {

        Boolean sourceHandledThisLoop = NO;
        int retVal = 0;
        do {

            /// 2. 通知 Observers: RunLoop 即将触发 Timer 回调。
            __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeTimers);
            /// 3. 通知 Observers: RunLoop 即将触发 Source0 (非port) 回调。
            __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeSources);
            /// 执行被加入的block
            __CFRunLoopDoBlocks(runloop, currentMode);

            /// 4. RunLoop 触发 Source0 (非port) 回调。
            sourceHandledThisLoop = __CFRunLoopDoSources0(runloop, currentMode, stopAfterHandle);
            /// 执行被加入的block
            __CFRunLoopDoBlocks(runloop, currentMode);

            /// 5. 如果有 Source1 (基于port) 处于 ready 状态,直接处理这个 Source1 然后跳转去处理消息。
            if (__Source0DidDispatchPortLastTime) {
                Boolean hasMsg = __CFRunLoopServiceMachPort(dispatchPort, &msg)
                if (hasMsg) goto handle_msg;
            }

            /// 通知 Observers: RunLoop 的线程即将进入休眠(sleep)。
            if (!sourceHandledThisLoop) {
                __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeWaiting);
            }

            /// 7. 调用 mach_msg 等待接受 mach_port 的消息。线程将进入休眠, 直到被下面某一个事件唤醒。
            /// ? 一个基于 port 的Source 的事件。
            /// ? 一个 Timer 到时间了
            /// ? RunLoop 自身的超时时间到了
            /// ? 被其他什么调用者手动唤醒
            __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort) {
                mach_msg(msg, MACH_RCV_MSG, port); // thread wait for receive msg
            }

            /// 8. 通知 Observers: RunLoop 的线程刚刚被唤醒了。
            __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopAfterWaiting);

            /// 收到消息,处理消息。
            handle_msg:

            /// 9.1 如果一个 Timer 到时间了,触发这个Timer的回调。
            if (msg_is_timer) {
                __CFRunLoopDoTimers(runloop, currentMode, mach_absolute_time())
            } 

            /// 9.2 如果有dispatch到main_queue的block,执行block。
            else if (msg_is_dispatch) {
                __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
            } 

            /// 9.3 如果一个 Source1 (基于port) 发出事件了,处理这个事件
            else {
                CFRunLoopSourceRef source1 = __CFRunLoopModeFindSourceForMachPort(runloop, currentMode, livePort);
                sourceHandledThisLoop = __CFRunLoopDoSource1(runloop, currentMode, source1, msg);
                if (sourceHandledThisLoop) {
                    mach_msg(reply, MACH_SEND_MSG, reply);
                }
            }

            /// 执行加入到Loop的block
            __CFRunLoopDoBlocks(runloop, currentMode);


            if (sourceHandledThisLoop && stopAfterHandle) {
                /// 进入loop时参数说处理完事件就返回。
                retVal = kCFRunLoopRunHandledSource;
            } else if (timeout) {
                /// 超出传入参数标记的超时时间了
                retVal = kCFRunLoopRunTimedOut;
            } else if (__CFRunLoopIsStopped(runloop)) {
                /// 被外部调用者强制停止了
                retVal = kCFRunLoopRunStopped;
            } else if (__CFRunLoopModeIsEmpty(runloop, currentMode)) {
                /// source/timer/observer一个都没有了
                retVal = kCFRunLoopRunFinished;
            }

            /// 如果没超时,mode里没空,loop也没被停止,那继续loop。
        } while (retVal == 0);
    }

    /// 10. 通知 Observers: RunLoop 即将退出。
    __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
}

看出实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回

###Event Loop(消息循环)概念

Event Loop(消息循环)就是do while死循环。这种机制的关键点就是如何管理事件/消息。比如;如何让在没有消息的时候线程休眠来避免资源占用,和在有消息是即时处理消息。runloop就是对它的优化。本质是一样的。

###类与对象的概念

####对象,类的实例,也就是类的一个对象,是类初始化的产物,

一个类初始化后成为一个实例,这个实例就是类的一个对象叫做对象,也叫做类的实例。简称对象

一个类可以有多个实例,由[alloc init ]方法获得,存储的是类的成员变量和方法

###类的结构:

oc对象的根类是NSObject

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

所以实际NSObject还是一个Class对象

在objc/runtime.h中objc_class结构体的定义如下:

struct objc_class {
   Class isa ;//指向自身类,也就是对象所属的类
    Class super_class  ;  // 父类
    const char *name  ;  // 类名
    long version     ;  // 类的版本信息,默认为0
   long info        ;  // 类信息,供运行期使用的一些位标识
   long instance_size ;  // 该类的实例变量大小
   struct objc_ivar_list *ivars    ;  // 该类的成员变量链表
   struct objc_method_list **methodLists  ;  // 方法定义的链表
   struct objc_cache *cache    ;  // 方法缓存
  struct objc_protocol_list *protocols ;  // 协议链表

};

###Isa指针 oc中每一个对象都是一个类的实例,在对象中有一个isa指针,指向该对象的类,也就是说 isa指针,指向类自身,根据这个isa指向就可以找到对象所属的类,

####元类(metaclass) 类也是一个对象,他是元类的实例,元类表达了类对象本身所具有的元数据,比如类方法列表

而且一个类只有一个类对象,即一个类只有一个元类,类就是对类对象的简称。

####元类的isa指针 所有元类的isa指针指向一个根元类(root metaclass)(NSObject),

根元类的isa指针指向自己,

在oc中跟类是NSObject,所以根元类也是NSObject。NSObject的元类的isa指向自己

###方法的调用规则是 无论是类方法还是类对象的方法的调用规则都是: 如果该类没有一个方法的实现,则向它的父类继续查, 所以所有的子类的元类都会继承父类的元类,也就是说类对象和元类对象(类)有相同的基础关系。

###方法结构体objc_method

单个方法的信息的存储结构体。

####定义

struct objc _method
{ 
SEL method_name; 
char *method_types, //参数
IMP method_imp
}

####SEL:方法选择器,存储的是方法的名字,是一个c字符串。

####IMP:方法的具体实现指针

方法名和方法实现是分开的。

###如何获取方法的IMP指针

mehtodForSelector

####方法中的隐藏参数

1.self指针,指向当前方法的对象 2._cmd指向方法的SEL指针

###runtime概念

runtime有叫运行时,是指将一些决定从编译器推迟到代码运行期来处理,

在oc中所有的一切都是对象,所以runtime机制就是说:只有在运行时才能真正确定类的相关信息,

故我们利用runtime机制可以在代码运行时获取并修改类的相关信息,比如获取类的方法列表,属性列表,添加方法.属性等。

runtime 自身有一套比较底层的c语言来实现,我们所写饿oc代码,在运行期都会被runtime处理为c语言,所以runtime是oc的幕后工作者。

###runtime可以实现的功能有哪些?

1.动态创建对象


2.获取类的方法类表,属性列表,协议列表,给类添加方法和属性,修改类的属性.方法的实现,给类添加协议

3.oc中分类不可以动态添加属性,但是可以通过属性关联来给分类添加属性。

4.一些类库不知道方法的功能是什么,可以通过方法混合来加入自己的打印语句知道方法的输入和输出是什么。从而指导方法的功能。

###runtime的消息机制 即为什么oc的方法调用叫做发送消息。

在oc,根据runtime的机制,消息只有到运行时才绑定到方法的实现上,

首先编译器将消息表达式[receive message] 自动转化为objc_msgSend(receive,selector)函数,其中,receiver是消息的接受者,selector代表方法名。

在objc_msgSend函数中。

1.首先通过receiver的isa指针找到receiver对应的类(class)

2.然后在类的方法缓存中查找方法(selector).找到就转到相应的实现执行,

3.如果在cache中没有找到方法,就会在类的方法列表(messageList)中去查找方法,找到就转到相应的实现执行

4.如果在isa执行所指向cache和messgelist都没有没到方法,就转向super所指向的父类进行2,3.操作

5.依次类推,如果知道跟类NSObject还是没有找到,就转向消息拦截

6.如果没有重写消息拦截调用,程序就会崩溃

###消息拦截即消息转发

目的是:在找不到调用的方法而导致程序崩溃前给程序一个机会进行处理,这个机会就是重写NSObject的四个方法,

第一步:动态方法解析

即使用runtime机制添加方法

重写 resolveClassMethod添加新的类方法或者重写resolveInstanceMethod添加新的实例方法注意二者默认返回NO,添加方法后需要返回YES。

if (aSEL == @selector(t))
     {
         class_addMethod([selfclass], aSEL, (IMP) dynamicMethodIMP, "v@:");
         return YES;
     }
     return [superresolveInstanceMethod:aSEL];
}

第二步:备援接收者

重写(id)forwardingTargetForSelector返回一个可以处理消息的对象

-(id)forwardingTargetForSelector:SEL
{
 if (aSelector == @selector(uppercaseString))
    {
        return self.carInfo;
    }
}

第三步:完整消息转发

重写- (void)forwardInvocation:(NSInvocation *)anInvocation;

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
 if ([someOtherObject respondsToSelector:

            [anInvocation selector]])

        [anInvocation invokeWithTarget:someOtherObject];

    else

        [super forwardInvocation:anInvocation];

}

有三种处理方式:

1.改变消息调用目标,系统会在新的调用目标方法列表中查询对应方法的实现并实现跳转, 2.修改方法的选择子,即修改方法名

3.向调用方法中追加一个参数等来跳转到相关方法的实现

第四步:抛出异常

调用NSObject的doesNotRecognizeSelector抛出异常

###runtime应用实例

####给分类通过属性关联添加属性

关联:是指把两个对象相互关联起来,其中的一个对象作为另一个对象的一部分。

关联是基于关键字的。所以只要关键字不同,可以给让任何两个对象关联起来,然后这两个对象就有了相同的生命周期。

get方法添加关联属性

objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

set根据key获取关联属性的值

objc_getAssociatedObject(self, key);

在不需要的时候可以移除关联属性

断开关联是使用objc_setAssociatedObject函数,传入nil值即可。

断开所有链接:objc_removeAssociatedObjects

####method Swizzle(黑魔法),是什么?什么时候使用?

mthod swizzle。方法混合。指的是改变一个已经存在的方法的实现过程,

#####原理是 方法名和方法实现是分开的,而且可以通过类的调度表可以改变其映射关系。

实现

1.根据api class_getClassMethod通过方法名找到方法的实现。

Method oriMethod = class_getInstanceMethod([self class], @selector(viewWillAppear:));

    Method swizzMethod = class_getInstanceMethod([self class], @selector(customViewWillAppear));

2.调用 mehtod——exchangeImp交换2个方法的实现

    method_exchangeImplementations(oriMethod, swizzMethod);

这样调用oriMethod实际上调用的是swizzMethod。然后在swizzMethod中手动调用oriMethod。并加入自己的代码,就可以知道系统方法oriMethod的输入和输出具体是什么。

###runtime如何实现weak属性?

通过属性关联

并设置关联属性的关联策略为OBJC_ASSOCIATION_ASSIGN

objc_setAssociatedObject(self, @"__delegate__key", delegate, OBJC_ASSOCIATION_ASSIGN);

###runtime如何实现weak变量的自动置nil?

runtime会将weak对象放入一个hash表中,hash表中以weak对象的内存地址为key,假设这个地址为a,

当weak对象的引用计数为0时,会在hash表中以a为键进行搜素这个weak对象。找到后设置为nil。

###weak有默认值吗?给nil 发消息安全吗?

weak修饰的指针默认值是nil,

在object-c中向nil对象发送消息是安全的。

给nil对象发送消息,是不会崩溃的,因为在oc中nil就是0.

那函数执行就会读取从函数开始位置偏移值为0的位置,还是函数调用开始的位置,自然什么也不不做就直接返回了。

至于要么返回默认的0,要么返回nil对象。要么返回0.0,则根据函数返回值决定。

###runtime如何通过selector找到相应的IMP地址?

selector是SEL类型。指的是方法名。

IMP:是方法的具体实现地址,二者是一一对应的关系,

通过selector可以直接找到IMP地址,方法是methodForSelector

###动态类型:id类型

程序直到运行时才能确定所属的类的类型,在oc中指的是id类型,id 通用的对象类型,本身是一个指针,可以指向任意类型的对象。

###动态绑定

动态绑定是指向在运行时确定要调用的方法,

因为在编译时,方法的调用并不和代码绑定在一起,只有在消息发送出来之后,才确定被调用的代码。

通过动态类型和动态绑定技术,代码每次执行都可以得到不同的结果。运行时根据消息分发机制确定消息的接收者和被调用的方法。

当我们发送一个消息给一个类的实例,这条消息会在实例所属类的方法中查找 当我们发送一个消息给一个类对象,这条消息会在类的元类meta calass 的方法中查找

###kvo与runtime

kvo是利用runtime 动态产生一个类的

###NSCoding与runtime

NSCoding的归档和解档利用runtime遍历对象的所有属性,然后根据属性名给属性赋值。

Hook学习
JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。