iOS开发之OC内存管理(二)

在OC中也有一种内存自动释放的机制叫做“自动引用计数”(或“自动释放池”),与C#、Java不同的是,这只是一种半自动的机制,有些操作还是需要我们手动设置的。

自动内存释放使用NSAutoreleasepool声明一个自动释放池,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)。看下面的代码:

HXStudent.h

#import <Foundation/Foundation.h>
#import "HXBook.h"

@interface HXStudent : NSObject
/**
 *  人名
 */
@property (nonatomic, copy) NSString *name;

- (instancetype)initWithName:(NSString *)name;
+ (instancetype)studentWithName:(NSString *)name;
@end

HXStudent.m

#import "HXStudent.h"

@implementation HXStudent

- (instancetype)initWithName:(NSString *)name {
    if (self = [super init]) {
        
        _name = name;
    }
    return self;
}
+ (instancetype)studentWithName:(NSString *)name {
    HXStudent *student = [[[self alloc] init] autorelease];// 因为有alloc,所以要autorelease,遵循原则
    student.name = name;
    
    return student;
}

- (void)dealloc {
    
    NSLog(@"销毁student,name = %@", _name);
    [super dealloc];
}

@end
在main函数中:

int main(int argc, const char * argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    HXStudent *student1 = [[HXStudent alloc] init];
    [student1 autorelease];// 因为有alloc,所有要autorelease
    student1.name = @"shx1";// 由于autorelease是延迟释放,所以这里仍然可以使用student1
    
    HXStudent *student2 = [[[HXStudent alloc] initWithName:@"shx2"] autorelease];// 因为有alloc,所有要autorelease
    
    HXStudent *student3 = [HXStudent studentWithName:@"shx3"];// 内部已经调用了autorelease,所以不需要手动释放,这也符合内存管理原则,因为这里并没有alloc所以不需要release或者autorelease
    
    NSLog(@"在这里之前没有销毁上面三个对象");
    //    [pool drain];// 添加该行代码,会一个提示(double release)
    [pool release];
    return 0;
}

如果将断点打在NSLog一行,可以看到程序运行到这里,三个对象还没有被销毁(打断点只是为了观察)。当执行[pool release]完毕的时候,三个对象才会被销毁。因此上面person1,调用完autorelase之后它还存在,因此给name赋值不会有任何问题;在OC中通常如果一个静态方法返回一个对象本身的话,在静态方法中我们需要调用autorelease方法,因为按照内存释放原则,在外部使用时不会进行alloc操作也就不需要再调用release或者autorelase,所以这个操作需要放到静态方法内部完成。

注意:

对象并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。

drain只是用于清除pool中对象,不会销毁池,release先调用drain方法清理对象,然后再释放自己内存。

对于自动内存释放简单总结一下:

    autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中;

    自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁);

    由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存(对象比较多或者对象占用资源比较多),最好不要放到自动释放池或者考虑放到多个自动释放池;

   OC中类库中的静态方法一般都不需要手动释放,内部已经调用了autorelease方法。

管理内存遵循的原则:谁创建谁释放。

以上是在非ARC环境下的自动释放池的内存管理原理。

 

对于在ARC(自动引用计数)环境下,简单理解就是,系统会在适合的时候,自动帮我们调用retian、release操作,不用我们在手动写这些代码。

在ARC环境下声明自动释放池只需要使用@ autoreleasepool关键字的代码块就可以生产自动释放池,不用alloc。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值