iOS开发内存管理

       首先 对ARC(AutomaticReference Counting)进行了解。ARC技术是能提供自动引用技术,省掉了让人烦人和容易遗漏的retain,release,autorelease等操作,其工作原理是将内存操作的代码(retain,release等)自动添加到需要的位置。即底层上使用和MRC手工引用技术一样的内存管理机制。需要注意的是:ARC是编译器(时)特性,而不是运行时特性。

      紧接着我们来谈谈ARC与MRC的问题:

(1)修饰属性(使用@property定义时)

读写控制:

    readwrite:可读可写,会生成getter和setter方法。

    readonly:只读,只会生成getter方法,不会生成setter方法。

引用方式:

    copy:拷贝,复制一个对象并创建strong关联,引用计数为1 ,原来对象计数不变。

    assign:赋值,不涉及引用计数的变化,弱引用。ARC中对象不能使用assign,但原始类型(BOOL、int、float)仍然可以使用。

    retain:持有,对原对象引用计数加1,强引用。ARC中使用strong。

    weak:赋值(ARC),比assign多了一个功能,对象释放后把指针置为nil,避免了野指针。

    strong:持有(ARC),等同于retain。

线程安全:

    nonatomic:非原子操作,不加同步,多线程访问可提高性能,但不是线程安全的。

    atomic:原子操作,与nonatomic相反。

  

(2)修饰变量(修饰不使用@property定义时,比如函数内的局部变量)

    __strong:是缺省的关键词,强引用。

    __weak:声明了一个可以自动置nil的弱引用(ARC中)。

    __unsafe_unretained:声明一个弱引用,但是不会自动nil化(只有iOS 4 才应该使用)。

    __autoreleasing:用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放(类似autorelease)。

这是一些概念上得不同。

这时候,我们就要问__strong,__weak  是怎么一回事,那么我们就介绍一下,强引用 与弱引用的问题:

强引用:当前对象被其他对象引用时,会执行retain操作,引用计数器+1。当retainCount=0时,该对象才会被销毁。因为我们要进行对象的内存管理,所以这是默认的引用方式。(默认是强引用)

弱引用:当前对象的生命周期不被是否由其他对象引用限制,它本该什么时候销毁就什么时候被销毁。即使它的引用没断,但是当它的生存周期到了时就会被销毁

接下来,在谈谈block 的引用问题:

在MRC中,用__block 修饰变量,他起到的作用是:

       1.说明变量课改

       2.说明指针指向的对象不做这个隐式的retain操作

然而,在ARC中,使用

__block __typeof(self) weakSelf = self;
    calendar.tapDate = ^(NSString *date){
        [weakSelf sayHi];
    };

发现  程序出现循环引用,无法释放内存的问题;

然后这样写:

__weak __typeof(self)weakSelf = self;

calendar.tapDate = ^(NSString *date){
        [weakSelf sayHi];
    };

是没有问题;

既然都是让block中捕获的指针指向的对象不要进行retain 操作,为何在ARC中__block就不起作用呢?

我认为:在ARC中,block的运行机制发生了变化,对__block 的捕获进行了修改,导致这个关键词失去了作用。

注意:(在Cocoa中: 在ARC引入后,没有了retain和release等操作,情况也发生了改变:在任何情况下,__block修饰符的作用只有上面的第一条:说明变量可改。即使加上了__block修饰符,一个被block捕获的强引用也依然是一个强引用)这句话的表述是有误的。ARC中仍然有retain 和release 操作。

因此:__block的两个作用都在,但是ARC捕获机制发生改变,不认识__block修饰的变量不进行retain操作。


这时候有又一个新问题出现:__weak在弱引用,在一般的单线程环境中,这种问题出现的可能性不大,但是到了多线程环境,就很不好说了,所以我们需要继续完善这个方法:

__weak __typeof(self)weakSelf = self;
    calendar.tapDate = ^(NSString *date){
      __strong __typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf sayHi];
    };

OK,到此解决问题。

下边附上注意事项:

1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。


参考:http://www.cocoachina.com/ios/20150206/11121.html



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值