@property 的本质是生成setter方法和getter方法以及一个带下划线的成员变量,经过autosynthesis添加到类中的。ios
一般的关键字为:objective-c
nonatomic & atomicsegmentfault
这是表明原子性 可是atomic不能彻底保证线程安全 它只保证了setter和getter方法的线程安全,具体的状况:当A线程进行写操做的时候,B线程会等待。当A线程写完,B线程进行写操做,而后A线程读取的将是B线程中的值,若是C线程在A线程读写前将对象release了还会形成程序崩溃api
strong & retain数组
strong至关于ARC下的retain 会强引用对象 使得对象的引用计数加一缓存
weak & assign安全
assign多被用来修饰基本数据类型,是指针赋值,不会对引用计数操做,使用以后不会自动置nil,可能会致使野指针。A对象的指针赋值给B,此时B只是保存了A的指针,不会持有A,因此当A被释放的时候再访问B可能会出现野指针错误。bash
weak表示弱引用,它既不会设置新值,也不会保存旧值。不会对引用计数操做,当指向的对象被释放以后,自身也会被置nil多线程
copy异步
copy是对对象的引用计数加一,它对应的setter方法不会保存新值,而是将其拷贝一份,一般NSString以及具备可变类型的集合类型可使用copy修饰,拷贝一份出来,以保证不会再使用的过程当中被其余地方的操做所改变
block也使用copy来修饰,这是MRC遗留下的传统,提示开发者block是从栈上复制到堆上的。
readwrite&readonly
读写,只读
setter= & getter=
指定setter方法和getter方法
默认
基本数据类型默认是assign, atomic,readwirte
对象类型strong,atomic, readwrite
@synthesize 自动生成setter getter方法
@dynamic不须要编译器生成,手动生成
默认是@synthesize var = _var
拷贝的本质是生成一份独立的副本
对不可变对象来讲 copy是浅拷贝,由于该对象自己就是不可变的了。而mutablecopy是深拷贝由于须要拷贝出来一份可变的对象,因此须要进行深拷贝,拷贝内存中的内容。
对可变对象来讲,copy和mutable拷贝都是深拷贝,copy生成的对象是不可变的,mutablecopy会生成可变对象
自定义对象想要进行copy操做须要实现NSCopying
协议
实现copyWithZone
或者mutableCopyWithZone
方法
- (id)copyWithZone:(NSZone *)zone {
Person *p = [[Person allocWithZone:zone] init];
//属性也要拷贝赋值
p.name = [self.name mutableCopy];
p.age = self.age;
return p;
}
复制代码
若是Person中有其余自定义对象,那么该自定义对象也须要实现遵循并实现 NSCopying
协议。
class_isMetaClass
来验证某个类是否是元类,其本质是一个 objc_class 的结构体。+ initialize
第一次初始化这个类以前调用,咱们经常使用来初始化静态变量,是runtime负责的。+load
方法会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载全部的类,就会调用每一个类的 + load 方法。load经过指针直接找到函数地址直接调用没有经过消息机制可使用Category为类添加新方法,使用Category为类添加新方法在必定程度上比使用继承添加方法的释放耦合度低。
category是不支持直接使用属性的,能够经过runtime的属性绑定来实现。声明一个属性,实现setter和getter方法。在setter方法中使用objc_setAssociatedObject
第二个参数标记能够用``@selector([getter method name]),getter方法中使用
objc_getAssociatedObject获取属性值,第二个参数使用
_cmd`
category 中实现的方法是在运行时添加到类中的。category是按照编译顺序排列的,因此后编译的cat中取出的方法、属性和协议列表,分别放在mlist、proplists和protolists的最前面。
block的本质是封装了函数调用和函数调用环境的OC对象
Block对变量的捕获:
block类型
MRC下 当block访问了auto类型变量的时候是stackblock 其余状况下是globalblock
ARC下会将stackblock从栈上copy到堆上,固然这是编译器帮咱们作的
ARC下的block会在一下状况自动调用copy方法
对象类型的捕获
__weak
ARC下一般使用__weak
来解决block的循环引用问题,使用它修饰的对象在被block捕获的时候,在block内部也会使用__weak
来修饰,而使用__weak
修饰的对象会被弱引用。
__block
在block内部修改auto变量的时候一般会报错,这个时候须要使用__block
修饰。__block
修饰的变量,在block内部会生成一个结构体,结构体中存放有isa指针__forwarding
指针,变量等信息,当改变变量的值得时候会经过__forwarding
指针找到这个结构体,改变其中变量的值。
_NSSetIntValueAndNotify
函数,它会在赋值以前调用willChangeValueForKey
,以后调用didChangeValueForKey
来监听值得改变。setKey
,_setKey
的顺序查找setter方法,若是找到则直接调用设置值,找不到则查看+ (BOOL)accessInstanceVariablesDirectly
方法的返回值,若是返回值是NO则调用setValue:forUndefinedKey
方法,若是没有实现会抛出异常。若是是YES,则会按照_key
,_isKey
,key
,isKey
的顺序查找成员变量赋值getKey
、key
、isKey
、_key
的顺序查找对应的方法,若是找到则展开调用,若是找不到那么查看+ (BOOL)accessInstanceVariablesDirectly
返回值,YES的话会按照_key
,_isKey
,key
,isKey
的顺序查找成员变量,返回NO的话就会调用- (id)valueForUndefinedKey:(NSString *)key
,若是没有实现会抛出异常+ (BOOL)accessInstanceVariablesDirectly
默认为YESiOS 使用引用计数的方式管理内存,内存管理的原则是谁建立,谁释放 。 谁引用,谁管理
使用new、alloc、copy或者mutable copy,引用计数为初始值1,再使用retain的话,引用计数为+1,使用release或者autorelease会使引用计数-1。
自动释放池,OC对象调用autorelase方法以后,会将对象放到离本身最近的自动释放池内,Run Loop在每一个事件循环结束后会去自动释放池,会将释放池内全部的对象都作一次release操做。
MRC下的setter方法
先释放旧值再引用新值
- (void)setAge:(NSString *)age {
if (_age != age) {
[_age release];
[age retain];
_age = age;
}
}
复制代码
iOS的多线程方案:
performSelector:onThread...
dispatch_queue_cretate
建立的,读写操做的时候可使用栅栏函数隔离写操做。首先会在方法缓存中查找方法的实现,若是没有找到则查找父类的实现,父类没有实现会进入动态方法解析,为该类添加一个方法的实现。若是动态方法解析尚未实现,那么会进入消息转发,将消息转发给一个能够相应该方法的target。若是这一步尚未实现则会进行方法签名,返回一个方法签名,并调用forwardInvacation
返回一个target处理该消息,若是尚未实现则会报方法找不到错误。
首先会通知监听者Observers:即将处理Timers
通知监听者Observers:即将处理Sources
处理blocks
处理source0,若是处理完了会再次处理blocks
若是存在source1,则跳到handle_msg处理,若是没有则通知监听器即将进入休眠
休眠时期等待消息来唤醒当前线程
若是有消息唤醒则进入handle_msg处理计时器,gcd,source1这些信息
再次处理blocks
获取返回值retVal
进入do-while()
,若是retVal == 0
则循环持续进行。不然返回给CFRunLoopRunSpecific
函数,退出RunLoop
visiableCells
中全部cell移入reusableTableCells
,visiableCells
清空。cellForRowAtIndexPath
调用后,再把reuse
的cell从reusableTableCells
取出来,放入到visiableCells
。reusableTableCells
为空,那么cellForRowAtIndexPath
调用后,是新建立cell,新的cell加入到visiableCells
。老的cell移出visiableCells
,加入到reusableTableCells
client向server发送请求https://baidu.com,而后链接到server的443端口。
服务端必需要有一套数字证书,能够本身制做,也能够向组织申请。区别就是本身颁发的证书须要客户端验证经过,才能够继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。
传送证书 这个证书其实就是公钥,只是包含了不少信息,如证书的颁发机构,过时时间、服务端的公钥,第三方证书认证机构(CA)的签名,服务端的域名信息等内容。
客户端解析证书 这部分工做是由客户端的TLS来完成的,首先会验证公钥是否有效,好比颁发机构,过时时间等等,若是发现异常,则会弹出一个警告框,提示证书存在问题。若是证书没有问题,那么就生成一个随即值(秘钥)。而后用证书对该随机值进行加密。
传送加密信息 这部分传送的是用证书加密后的秘钥,目的就是让服务端获得这个秘钥,之后客户端和服务端的通讯就能够经过这个随机值来进行加密解密了。
服务段加密信息 服务端用私钥解密秘密秘钥,获得了客户端传过来的私钥,而后把内容经过该值进行对称加密。
传输加密后的信息 这部分信息是服务端用私钥加密后的信息,能够在客户端被还原。
客户端解密信息
客户端用以前生成的私钥解密服务端传过来的信息,因而获取了解密后的内容。
上述文字出自HTTP和HTTPS协议,看一篇就够了