多线程与内存管理

2017-07-20  本文已影响0人  angry_zxy

自动引用计数

内存管理&引用计数

GNUstep中引用计数的实现

苹果中引用计数的实现

苹果的实现与CNUstep类似,不同的是,GNUstep将引用计数保存在对象占用内存头部的变量中,而苹果的实现,则是保存在引用计数表的记录中。

内存头部管理VS引用计数表管理

内存头部管理:

引用计数表管理:

autorelease

autorelease会像C语言的自动变量那样来对待对象实例,当超出其作用域时,对象实例的release实例方法被调用。
具体使用方法:
1 生成并持有NSAutoreleasePool对象
2 调用已分配对象的autorelease实例方法
3 废弃NSAutoreleasePool对象
调用NSObject类的autorelease实例方法,该对象将被追加到正在使用的NSAutoreleasePool对象中的数组里

通常在使用OC,也就是Foundation框架时,无论调用哪一个对象的autorelease方法,实现上的调用都是NSObject类的autorelease实例方法。但是对于NSAutoreleasePool类,autore实例方法已被该类重载,因此运行时就会出错

-__

ARC规则

所有权修饰符

为什么在访问附有_ _weak修饰符的变量时必须访问注册到autoreleasePool的对象呢?
这是因为__weak修饰符只持有对象的弱引用, 而在访问引用对象的过程中, 该对象有可能被废弃. 如果要把访问的对象注册到 autoreleasePool 中, 那么@ autoreleasePool 块结束之前都能确保该对象存在.

ps: NSObject **obj等效于NSObject * __autoreleasing *obj.

规则

  • init
    以 init 开始的方法的规则要比 alloc/new/copy/mutableCopy更严格.该方法必须是实例方法,并且必须返回对象, 返回的对象应为 id 类型或该方法声明类的对象类型, 抑或是该类的超类型或子类型.该返回类型并不注册到 autoreleasePool上,基本上只是对 alloc方法返回值的对象进行初始化处理并返回该对象

属性

在 ARC 有效时:
assign --- __unsafe_unretained
copy --- __strong
retain --- __strong
strong --- __strong
unsafe_retain --- __ansafe_retain
weak --- __weak

ARC 的实现

__strong 的实现

__weak的实现

Blocks

blocks 概要

^ 返回值类型 参数列表 表达式

blocks 实现

struct __main_block_impl_0 {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
struct __main_block_desc_0 *Desc;
}

该结构体构造函数会这样初始化:

isa = &_NSConcreteStackBlock;
Flags = 0;
Reserved = 0;
FuncPtr = __main_block_func_0;
Desc = &__main_block_desc_0_DATA;

对于isa = &NSConcreteStackBlock的理解:
_NSConcreteStackBlock 相当于 class_t 结构体实例, 在将 block 作为 OC 对象处理时, 关于该类的信息放置于_ NSConcreteStackBlock 中.

自动变量的截获

__Block

block 存储域

__block 变量存储域

截获对象

循环引用

Grand Central Dispatch(GCD)

GCD 是异步执行任务的技术之一. 一般将应用程序中记述的线程管理用的代码在系统级中实现. 开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue 中, GCD 就能生成必要的线程并计划执行任务. 由于线程管理是作为系统的一部分来实现的, 因此可统一管理, 也可执行任务 这样就比以前的线程更有效率.

dispatch_queue_create

dispatch_set_target_queue

dispatch_set_target_queue可以变更 Dispatch Queue 的执行优先级

dispatch_after

Dispatch Group

dispatch_barrier_async

dispatch_apply

Dispatch Semaphore

Dispatch Queue 没有取消的概念, 一旦将处理追加到 Dispatch Queue 中, 就没有方法可将该处理去除. Dispatch source 则可以取消

上一篇 下一篇

猜你喜欢

热点阅读