-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoc的基本语言特性.txt
40 lines (20 loc) · 2.98 KB
/
oc的基本语言特性.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
这里主要讨论oc的内存管理,类与消息机制。
不要使用retainCount,因为:
retainCount返回的保留计数只是某个给定时间点上得值,这个方法并没有考虑到系统稍后会把自动释放池清空,因而不会将后续的释放操作从返回值里减去,这样的话就未必能真实反映实际的保留计数了!
///////////////////////////
while([object retainCount])
{
[object release];
}
///////////////////////////
这种写法是错误的,它没有考虑到后续的自动释放操作,只是不停的通过释放操作来降低保留计数,直至对象被系统回收,假如此时对象也在自动释放池里那么稍后系统清空池子时还要把它再释放一次这会导致程序崩溃!
第二个错误在于retainCont可能永远不会返回0,系统有时会优化对象的释放行为,在保留计数为1的时候就把它回收了,只在系统不打算这么优化时计数才会递减至0;
【13】Nsstring *string = @"hello frankfan";
【14】Nsnumber *number = @1;
【15】NsNumber *number2 = @3.14f;
用Clang4.1编译后,13行的retainCount为2^64-1|||||14行的retainCount为2^63-1,因为这两者都为单例对象所以保留对象都很大,系统会尽可能的把NSString实现为单例对象,在上面代码这种情况下,编译器会把NSString对象所表示的数据放到应用程序的二进制文件里,这样直接运行程序就可以用了,无需再创建NSString对象。NsNumber也类似,它使用了一种叫做“标签指针”(tagged pointer)的概念来标注特定类型的值,这种做法不使用NSNumber对象,而是把与数值有关的全部消息都放在指针值里面。运行期系统会在消息派发期间检测到这种指针,并执行相应操作,使其行为和真正的NSSnumber对象一样,这种优化只在某种场合使用,比如上面的浮点数对象就没有优化,所以保留技数就是1;
另外,像刚才说的那种单例对象,其保留计数绝对不会变,这种对象的保存释放操作都是空操作(no-op)。可以看到即便两个单例之间其保留计数也各不相同;
////////////////////////////////////////////////////////////////////////////
在ARC环境下我们不能手动显视使用retain,release,dealloc等方法,ARC在编译时会为我们自动插入相应的持有释放操作,不过ARC在调用这些方法时并不是通过普通的oc消息派发机制,而是直接调用其底层的C语言版本,因为保留和释放操作很频繁所以直接调用底层函数能节省更多的CPU周期,比方说ARC会调用与retain等价的底层函数objc_retain;
////////////////////////////////////////////////////////////////////////////
在ARC环境下除了自动调用保留释放操作外,还会在编译期把能够相互抵消的retain,release,autorelease操作简约,如果发现在同一个对象上执行多次保留与释放,那么ARC有时可以成功的移除这两个操作。