天天看点

oc——类——MRC ARC

RC

reference counting,引用计数,instance object内存管理机制,表示instance object被多少个指针引用或拥有 RC = 0时,instance object自动调用dealloc,instance object销毁,因此勿手动调用dealloc,否则会导致多次调用dealloc(多次销毁instance object)

MRC

mannul reference counting,手动引用计数,一种RC管理机制,开发者手动管理RC,MRC机制易导致RC混乱,引发内存错误 常见内存错误:

  • 没有销毁instance object(内存泄露)
  • 提早销毁instance object(访问非法内存)
  • 重复销毁instance object(访问非法内存)

RC相关方法:

- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE;
           

注1:protocol NSObject接口,NSObject class实现,MRC下才能调用,ARC下禁止调用 注2:MRC编译选项:-fno-objc-arc

@interface FBAnimal : NSObject

@end

@implementation FBAnimal

- (void)dealloc
{
    NSLog(@"dealloc FBAnimal");
    [super dealloc];
}

@end

@interface FBDog : FBAnimal

@end

@implementation FBDog

- (void)dealloc
{
    NSLog(@"dealloc FBDog");
    [super dealloc];
}

@end
           
- (void)use_mrc
{
    FBDog *dog = [[FBDog alloc] init];
    NSLog(@"RC = %lu", dog.retainCount);
    [dog retain];
    NSLog(@"RC = %lu", dog.retainCount);
    [dog release];
    NSLog(@"RC = %lu", dog.retainCount);
    [dog retain];
    NSLog(@"RC = %lu", dog.retainCount);
    [dog release];
    NSLog(@"RC = %lu", dog.retainCount);
    [dog release];
    NSLog(@"method end");
}
           

output:

RC = 1
RC = 2
RC = 1
RC = 2
RC = 1
dealloc FBDog
dealloc FBAnimal
method end
           

注:dealloc调用后,对象已释放,此时获取的RC值无意义

ARC

automatic reference counting,自动引用计数,一种RC管理机制,编译器替开发者插入RC相关方法调用,ARC下禁止调用RC相关方法,否则会导致RC混乱,引发内存错误 ARC下禁止调用RC相关方法并不表示ARC放弃instance object的RC内存管理机制,实际上还是RC机制(要不就不使用ARC这个明显使用RC的名字了),ARC下编译器替开发者插入RC相关方法调用,目的是为了减轻开发者负担,减少内存出错状况,提高开发效率 注1:ARC为默认RC管理机制 注2:ARC编译选项:-fobjc-arc

@interface FBAnimal : NSObject

@end

@implementation FBAnimal

- (void)dealloc
{
    NSLog(@"dealloc FBAnimal");
    //[super dealloc];
}

@end

@interface FBDog : FBAnimal

@end

@implementation FBDog

- (void)dealloc
{
    NSLog(@"dealloc FBDog");
    //[super dealloc];
}

@end
           
- (void)use_arc
{
    FBDog *dog = [[FBDog alloc] init];
    //NSLog(@"RC = %lu", dog.retainCount);
    //[dog retain];
    //NSLog(@"RC = %lu", dog.retainCount);
    //[dog release];
    NSLog(@"method end");
}
           

output:

method end
dealloc FBDog
dealloc FBAnimal
           

注1:dog指向instance object,此时RC = 1,离开use_arc后,dog失效,RC减1,此时RC = 0,调用FBDog的dealloc 注2:ARC下,禁止调用RC相关方法,禁止调用dealloc,编译器会自动在dealloc方法末插入[super dealloc]调用父类dealloc,如果手动插入,就会导致[super dealloc]重复调用(重复销毁父类),导致内存错误