Tagged Pointer
通常創(chuàng)建對象,對象存儲在堆中,對象的指針存儲在棧中。
我們要找到這個對象,就需要先在棧中,找到指針,然后通過指針找到堆中的對象。
這個過程比較繁瑣,當存儲的對象只是個很小的東西,比如字符串,數(shù)字,走這個繁瑣的過程,耗費性能。
從64bit開始,iOS 引入了Tagged Pointer技術,用于優(yōu)化NSNumber、NSDate、NSString等小對象的存儲
在沒有使用Tagged Pointer之前, NSNumber等對象需要動態(tài)分配內(nèi)存、維護引用計數(shù)等,NSNumber指針存儲的是堆中NSNumber對象的地址值.
使用Tagged Pointer之后,NSNumber指針里面存儲的數(shù)據(jù)變成了:Tag + Data,也就是將數(shù)據(jù)直接存儲在了指針中.
當指針不夠存儲數(shù)據(jù)時,才會使用動態(tài)分配內(nèi)存的方式來存儲數(shù)據(jù).
objc_msgSend能識別Tagged Pointer,比如NSNumber的intValue方法,直接從指針提取數(shù)據(jù),節(jié)省了以前的調(diào)用開銷.
// 是否是tagger pointer
- (void)test {
NSNumber *number1 = @4;
NSNumber *number2 = @5;
NSNumber *number3 = @(0xFFFFFFFFFFFFFFF);
NSLog(@"%d %d %d", [self isTaggedPointer:number1], [self isTaggedPointer:number2], [self isTaggedPointer:number3]);
NSLog(@"%p %p %p", number1, number2, number3);
}
set方法,會先release
-(void)setName:(NSString *)name{
if(_name != name){
[_name realease];
_name = [name copy];
}
return _name;
}
多線程release會導致crash