Objective-C之ARC

一.ARC:自动引用计数,即ARC。系统自动帮助我们去计算对象的引用计数器的值。


在程序中使用ARC非常简单,只需要像往常那样编写代码,只不过永远不要写retain、release、autorelease 

允许重写dealloc,但是不允许调用[super dealloc];


特别注意的是ARC是编译器机制,当ARC开启时,编译器会自动的在合适的地方插入retain、release、autorelase代码,自动为对象做引用计数。


二.ARC判断标准:

本质: 对象的引用计数器为0的时候,自动释放。
表象: 只要没有"强指针"指向这个对象,这个对象就会立即回收。

就算此时仍有 "弱指针" 指向该对象或者该对象还指向其他对象,只 要没有强指针指向它就会释放对象。

系统还会根据弱指针的情况及时释放弱指针对象,避免野指针的产生。


指针分为两种:

1.强指针:

强指针:默认情况下,声明一个指针,这个指针就是一个强指针。

我们也可以使用 _Strong 来显示声明这个是个强指针。

Person *p1;//这是个强指针,指针默认情况下都是个强指针
_strong person *p2 //这也是个强指针,使用_Strong来显示的声明强指针.

 2.弱指针:

使用_weak标示的指针就叫弱指针.

_weak Person *p3 = [[Person alloc] init];//一般这样创建,马上被释放

无论是强指针还是弱指针,都是指针,都可以用来存储地址,这1点没有任何区别,都可以通过这个指针访问对象的成员。

  1. 唯一的区别就是在ARC模式下,他们用来作为回收对象的基准。
    如果1个对象没有任何强类型的指针指向这个对象的时候,对象就会被立即自动释放

ARC下的单个对象的内存管理:

在ARC的机制下: 当1个对象没有任何的强指针指向它的时候,这个对象就会被立即回收。

 1.当1个对象没有任何的强指针指向它的时候,这个对象就会被立即回收:

int main(int argc,const char * argv[])
{

   @autoreleasepool
   {
     Person *p1 = [Person new]; p1强指针
     Person *p2 = p1; p2也是个强指针,p1和p2 都指向同一个Person对象
}当执行到这里的时候,p1,p2被回收,person对象没有强指针指向,那么就被回收.

return 0;
}

2.将所有指向对象的强指针赋值为nil的时候.对象就会被立即回收.

int main(int argc, const char * argv[])
 {
     @autoreleasepool
     {
         Person *p1 = [Person new];//p1是1个强指针.
         //因为我们说过,每1个指针变量默认情况下都是1个强指针变量.        
         p1 = nil;//当执行到这句话的时候.p1赋值为nil.
         //p1指针不再指向Person对象.
         //Person对象没有被任何的指针所指向,所以.Person对象在这里被释放.
         NSLog(@"------");
     }
     return 0;
 } 
 这两种情况就叫做没有任何强指针指向对象.
 1). 指向对象的所有强指针被回收掉
 2). 指向对象的所有的强指针赋值为nil


3.ARC机制下释放1个对象的标准是: 没有任何强指针指向对象的时候,对象就会被释放,如果这个时候有弱指针指向,也会被释放.

int main(int argc, const char * argv[])
 {
     @autoreleasepool
     {
         //使用__strong来标识p1指针是强类型的,其实不写__strong也是强类型的.
         __strong Person *p1 = [[Person alloc] init];
         
         //使用__weak标识指针p2的类型是弱类型指针.
         __weak Person *p2 = p1;
         //这个时候,p2指针和p1指针都指向Person对象.
         
         //这个时候如果设置p1的值为nil
         p1 = nil;
         //这个时候Person对象只有被1个弱指针p2指向,没有任何强指针指向
         //所以Person对象在这里被回收.

    p1对象被释放后,p2用weak声明的弱指针变量指向nil

     }
     return 0;
 }

4.最重要的1点:不能创建对象用1个弱指针存储这个对象的指针,这样的话,刚创建出来的对象,就没有任何强指针指向,创建出来就会被回收

int main(int argc, const char * argv[])
 {
     @autoreleasepool
     {
         //创建1个对象,将这个对象的地址赋值给1个弱指针
         //后果就是创建出来的这个对象没有被任何强指针指向.
         //刚创建出来就会被释放.
         __weak Person *p1 = [[Person alloc] init];
         
     }
     return 0;
 }


5.在ARC机制下,当对象被回收的时候,原来指向这个对象的弱指针会被自动设置为nil。

 Person *p1 = [Person new];
 __weak Person p2 = p1;
 p1 = nil;
//p2,被回收,向空指针发送消息不会报错的
 [p2 sayHi];

@property参数: 

 * strong :成员变量是强指针(适用于 OC 对象类型) 默认

* weak :成员变量是弱指针(适用于 OC 对象类型)

* assign : 适用于非 OC 对象类型

使用建议
1). 在ARC机制下,如果属性的类型是OC对象类型的,绝大多数场景下使用strong。
2). 在ARC机制下,如果属性的类型不是OC对象类型的,使用assign。
3). strong和weak都是应用在属性的类型是OC对象的时候,属性的类型不是OC对象的时候就使用assign。

4).在ARC机制下,当两个对象相互引用的时候,如果两边都使用strong 那么就会内存泄露。解决方案: 1端使用strong 1端使用weak:

最后不会走dealloc方法.

 


JAVA的垃圾回收机制 - GC: 程序在运行的期间,有1个东西叫做垃圾回收器,不断的扫描堆中的对象是否无人使用。
ARC: 不是运行时,而在编译的时候就在合适的地方插入retain 等操作,插入的代码足以让对象无人使用的时候,引用计数器为0,对象被回收

猜你喜欢

转载自blog.csdn.net/null959_/article/details/81156390