iOS开发中的ARC内存管理机制(1)——基础概念

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33737036/article/details/81261796

由于移动设备的内存资源一般比较少,所以垃圾回收机制的操作会对设备的性能造成比较明显的影响,有可能在执行垃圾回收的时候让移动设备出现卡顿,这对于使用者来说是很难受的事。

由此苹果公司提出了ARC方案。

 

0x01 自动引用计数

自动引用计数(Automatic Reference Counting,ARC),ARC会追踪程序中的对象并决定哪一个仍会使用到而哪一个不会再用到,在编译期,ARC就已经用更底层的C接口实现了retain/release/autorelease,性能非常好;

不同于垃圾回收器(GC)通过返回的代码来定期检查对象,占用了系统资源。

如果启用了ARC,只管像平常一样按需分配并使用对象,编译器会帮我们插入retain/release语句,相当于编译器替我们完成了内存管理的工作。

 

0x02 编写ARC代码所需的条件

1、能够确定哪些对象需要进行内存管理

该条件要求对象的最上层集合应该知道如何去管理它的子对象。如果对象是不可保留的,则无法使用ARC特性:

NSString **myString;
myString = malloc(10 * sizeof(NSString *));

//C风格数组是不可保留的对象,不能使用ARC特性

2、能够表明如何去管理对象

该条件要求程序员能够对某个对象的引用计数器值进行+1 / -1操作,NSObject类的子类都能进行内存管理;

3、有可行的办法传递对象的所有权

该条件要求程序能够在调用者和接收者之间传递对象的所有权;

4、编译环境及使用环境:

  • Xcode 4.2以上版本;
  • Apple LLVM 3.0以上版本的编译器;
  • MAC OS X 10.7以上版本的系统;
  • 包括归零弱引用(Zeroing Weak Reference),需要iOS 5.0或MAC OS X 10.7以上版本的支持。

 

0x03 ARC的使用规则

1、代码中不能使用retain、release、retain和autorelease方法;

2、不重载dealloc方法(如果是释放对象内存以外的操作是可以重载该函数的,但是不能直接调用[super dealloc]);

3、不能使用NSAllocateObject和NSDeallocateObject;

4、不能在C结构体中使用对象指针;

5、id与void *间的如果发生所有权传递时需要用特定的方法(__bridge关键字);

6、不能使用NSAutoReleasePool,而需要使用@autoreleasepool块;

7、不能使用“new”开始的属性名称 (如果使用会有下面的编译错误”Property’s synthesized getter follows Cocoa naming convention for returning ‘owned’ objects”);

8、属性不能只有一个read-only而没有内存管理属性,必须指定由谁来管理内存。

 

0x04 使用ARC的优点

使用ARC后写Objective-C代码就不需要操心复杂的内存管理和担心内存泄露了,把内存管理工作交给编译器,也有利于提高代码效率。最直观的一点就是代码总量变少,更容易阅读:

使用ARC前:

@interface NonARCObject : NSObject {    
    NSString *name;    
}    
-(id)initWithName:(NSString *)name;    
@end    
   
@implementation NonARCObject    
-(id)initWithName:(NSString *)newName {    
    self = [super init];    
    if (self) {    
        name = [newName retain];    
    }    
    return self;    
}    
   
-(void)dealloc {    
    [name release];    
    [Super dealloc];    
}    
@end    

使用ARC后:

@interface ARCObject : NSObject {    
    NSString *name;    
}    
-(id)initWithName:(NSString *)name;    
@end    
   
@implementation ARCObject    
-(id)initWithName:(NSString *)newName {    
    self = [super init];    
    if (self) {    
        name = newName;    
    }    
    return self;    
}    
@end    

 

 

展开阅读全文

没有更多推荐了,返回首页