一·Five area
stack:function
heap: which is created objc and block by alloc will store in heap area
bss:uninit-var static
data:init-var static
text:coding word which will inject in mem
二·targetpointer
1.setter修饰小对象类型
objc_retain/release{
if(!obj) return obj;
if(obj->isTaggedPointer()) return obj;
return obj->retain/release()
}
解决过渡释放的方法之一,直接返回对象,不返回retain/release
2.initializeTaggedPointerObfuscator
Pull random data into the variable ,then shift away all non-payload bits
将随机数据拉入变量,然后移出所有非有效负载位
arc4random_buf(&objc_debug_taggedpointer_obfuscator)
objc_debug_taggedpointer_obfuscator &= ~_OBJC_TAG_MASK;
与等于 MASK取反
return ptr ^ objc_debug(taggepointer_obfuscator)
return ptr ^ objc_enbug(taggepointer_obfucasor)
小对象的指针地址 通过了1.decode 异或一次 2.encode异或二次
也就是说targetpointer的地址 通过异或一次掩饰过后的地址就可以得到
三.targetpointer地址的特殊含义
targetpointer我们先把它简称为PT
_OBJC_TAG_MASK(1UL<<63)
mask保留了最高位的值0xb
拿到最高位的地址再做一次判断是否为taggetpointer
0xa :string 1 010
0xb :int 1 011
剩下的位置为tag的类型标识码
//60-bit payloads
OBJC_TAG_NSAtom =0,
OBJC_TAG_1 =1,
OBJC_TAG_NSString =2,
OBJC_TAG_NSNumber =3,
OBJC_TAG_NSIndexPath=4,
OBJC_TAG_NSManagedObjectID=5,
OBJC_TAG_NSDate =6,
作用:可以由系统自动回收,自动管理
字符串范围字串 | <8 | [8,10) | [10,11] | >11 |
---|---|---|---|---|
eilotrm,apdnslc | TP | TP | TP | OC |
eilotrm,apdnslC4013 & UL20856P | TP | TP | OC | OC |
128个ASCII | TP | OC | OC | OC |
四·MRC&ARC
1.retain/release
如果不是nonpointerisa 直接操作散列表
散列表结构
spinlock_t slock;
RefcountMap refcnts;
weak_table_t weak_table;
在内存里面有多少张散列表,最大值和最小值分别是什么?
散列表实际上是一张哈希表,结合了两种数据结构(数组链表),既方便查找,又方便插入
IPhone 有8张,其他64张
2.dealloc
objc_object::rootDealloc(){
if(fastpath(isa.nonpointer &&
!isa.weakly_referenced &&
!isa.has_assoc &&
!isa.has_cxx_dtor&&
!isa.has_sidetable_rc
)
析构:1.cxx析构 2.关联对象释放 3.弱引用表析构 4.散列表析构
{
asert(!sidetabel_present());
free(this);
}
最后才free()
}
3.EXTRA_RC操作引用计数
RC_ONE(1ULL<<45)
RC_HALF(1ULL<<18)
结合isa的64位结构的存储数据不同,若需要对引用计数处理,必须先找到头位
newisa.bits=addc(newisa.bits,RC_ONE,0,&CARRY);
//extra_rc
4.carry引用计数表超标
如果引用计数表满了
newisa.extra_rc=RC_HALF
那么extra_rc 分开一半
RC_HALF 一般给 extra_rc
RC_HALF 另外一半给sidetable_addExtraRC_nolock(RC_HALF)
5.retainCount
if(bits.nonpointer){
rc=1 bits.extra_rc; //alloc 创建的引用计数为0
if(bits.has_sidetable_rc){
rc = sidetable_getExtraRC_nolock();
}
sidetable_unlock()
return rc
}
默认返回为1