#import <Foundation/Foundation.h>

@interface Test : NSObject
/**
* 默认的就是__strong,这里只是做示范,实际使用时,不用写。
*
* @param obj <#obj description#>
*/
- (void)setObject:(id __strong)obj;
@end
#import "Test.h"
@interface Test(){ id __strong obj_; /** 默认的就是__strong,这里只是做示范,实际使用时,不用写。*/ }
@end
@implementation Test - (void)setObject:(id)obj{ //设置成员变量的值
obj_ = obj;
} @end

ARC的学习

使用ARC时,id类型和对象类型上必须加上所有权修饰符,所有权修饰符分为下面四种,一.是__strong,强引用(id类型和对象类型默认的就是这个修饰符,如成员变量,所有前面什么也不加,就是__strong)

是__weak弱引用,一般不会持有对象。三.是__unsafe_unretained修饰符。 四. 是__autoreleasing修饰符。

一.   __strong 的使用

特点

1.强引用,会持有对象,但会造成两个类或对象之前互相引用,造成循环引用。

2.超出作用域,强引用失效,会被释放。

3. 栗子1,循环引用,循环引用的重点就是最后引用的的那个对象是否为空,如果持有的对象已经废弃了,那个引用还存在,说明内存泄漏了,不能合理的翻译该对象。

   id  test1 = [[Test alloc] init];     /**test1 持有对象A的强引用*/
id test2 = [[Test alloc] init]; /**test2 持有对象B的强引用*/ [test1 setObject:test2]; /**Test对象A的成员变量obj_持有Test对象B的强引用,此时持有Test对象B的强引用为Test对象A的成员变量obj_和test2*/
[test2 setObject:test1]; /**Test对象B的成员变量obj_持有Test对象A的强引用,此时持有Test对象A的强引用为Test对象A的成员变量obj_和test1*/ /**1.因为test1变量超出作用域时,强引用会失效,会自动释放Test对象A*/
/**2.因为test2变量超出作用域时,强引用会失效,会自动释放Test对象B*/
/**3.此时持有Test对象A的强引用变量为Test对象B的成员变量obj_*/
/**4.此时持有Test对象B的强引用变量为Test对象A的成员变量obj_*/
/**5.发生内存泄漏*/

3.什么是内存泄漏?

/**内存泄漏是应当废弃的对象,在赶出自己的生命周期后继续存在*/

4.自己持有自己,不会造成内存泄漏,因为超出其生命周期时,会正常释放。

   id  test0 = [[Test alloc] init];

    [test0 setObject:test0];

5. 如何避免内存泄漏

二. __weak的使用

特点

1.避免循环引用

2.当一个对象对使用弱引用时,若对象被废弃时,该对象会被置为空

3.不支持iOS4及以下和OS X Snow Leopard

#if 0  //强引用的话,最终obj1还会持有对象。
id obj1 = nil; //默认的是用__strong修饰
{
id obj0 = [[NSObject alloc] init];
obj1 = obj0; /**强引用持有obj0*/ NSLog(@"obj1=%@,obj0=%@",obj1,obj0); //打印结果, obj1=<NSObject: 0x7fbcf3417220>,obj0=<NSObject: 0x7fbcf3417220>
}
/**obj0已经被废弃了,但obj1还持有它*/
NSLog(@"强引用超出作用域被废弃后obj1=%@",obj1); // 弱引用超出作用域被废弃后obj1=<NSObject: 0x7fbcf3417220> #endif
#if 0 //弱引用的话,最终obj1为nil id __weak obj1 = nil; //默认的是用__strong修饰,现在这里弱引用这个对象,并不持有它 { id obj0 = [[NSObject alloc] init]; obj1 = obj0; NSLog(@"obj1=%@,obj0=%@",obj1,obj0); //打印结果, obj1=<NSObject: 0x7fbcf3417220>,obj0=<NSObject: 0x7fbcf3417220> } NSLog(@"弱引用超出作用域被废弃后obj1=%@",obj1); // 打印结果,弱引用超出作用域被废弃后obj1=(null) #endif

三.  __unsafe_unretained的使用

特点

1.当使用iOS4及以下和OS X Snow Leopard时,会用到__unsafe_unretained,主要目的是在iOS4及以下和OS X Snow Leopard中代替__weak的。

#if 1 //__unsafe_unretained的话,最终会抛出异常或恰巧正常运行。
id __unsafe_unretained obj1 = nil; //默认的是用__strong修饰,现在这里弱引用这个对象,并不持有它
{
id obj0 = [[NSObject alloc] init];
obj1 = obj0; NSLog(@"obj1=%@,obj0=%@",obj1,obj0); //打印结果, obj1=<NSObject: 0x7fbcf3417220>,obj0=<NSObject: 0x7fbcf3417220>
}
NSLog(@"__unsafe_unretained超出作用域被废弃后obj1=%@",obj1); //objc1表示变量的对象,已经被废弃(悬垂指针)!错误访问!,也就是说,最后一行的NSLog只是碰巧正常运行而已,虽然访问了已经废弃的对象,但应用程序在个别情况下 #endif

四. __autoreleasing 的使用,在ARC中不允许使用autorelease和自动释放池pool,但autorelease是真实存在的。

arc下有效的方法

@autoreleasepool {
id __autoreleasing obj = [[NSObject alloc] init]; //obj,超出释放池之后会被自动释放
}

相当于mrc下的NSAutoreleasePool

#if 0

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    //如obj,要做耗时操作,如加载大量图片等等

     id  obj = [[NSObject alloc] init];

     [objc autorelease];

    [pool drain];

#endif

除alloc/new/copy/mutableCopy创建的对象不会注册的aureleasePool外,其他的都会注册到,如__weak,其他情况即为“取得非自己生成持有的对象”,这些务必牢记,为了在使用参数取得对象时,贯彻内存管理的思考方式,我们要将参数声明附有__autorelease的修饰符指针

//***__strong修饰符和__weak修饰符类似于C++中的智能指针,std::shared_ptr和weak::shared_ptr,前者也是强引用,后者也是避免循环引用***//

不要显式调用dealloc,如【self dealloc】,下面是可行的

//------------------------ARC下内存管理规则,不能使用或不推荐使用的-----------------------//

1.对象变量不能作为C语言的结构体成员,

 struct data{
// NSMutableArray *array; //成员变量,因为这是Objective-c中故有的对象,所以不能作为成员变量。
NSMutableArray __unsafe_unretained *array; // 这样的话可以在Objective中使用,但__unsafe_unretained不属于内存管理的对象,所以会造成内存泄漏。
NSInteger name;
}data1,data2; //data1,data2是变量名
data1.name = ;
data2.name = ;
NSLog(@"结构体打印%ld,%ld",data1.name,data2.name);
//2.显式转换id与void*的转换, 通过 __bridge 可以显式转换id与void*的转换
id obj = [[NSObject alloc] init];
void *p =(__bridge void *)obj;
id obje = (__bridge id)p;

__bridge 还有两种转换,__bridge_retained(使用后对象还存在相当于retain),__bridge_transfer(使用后对象被释放,相当于release),ARC中不推荐使用

但这样是可以转换,其安全性与__unsafe_unretained类似甚至会更低,如果管理者不注意赋值对象的所有者就会因悬垂指针而导致程序崩溃

//*** 悬垂指针 :指向曾经存在的对象,但该对象已经不再存在了,此类指针称为悬垂指针。结果未定义,往往导致程序错误,而且难以检测。***/

Objective C中的ARC的修饰符的使用---- 学习笔记九的更多相关文章

  1. Java 中的 protected 访问修饰符你真的了解吗?

    protected Java 中的 protected 访问修饰符 总结 在同一个包中,类中 protected 或 default 修饰的属性或方法可以在类外被其对象 (实例) 外部访问,也可以被子 ...

  2. iOS中copy和strong修饰符的区别

    iOS中copy和strong修饰符的区别 //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错 @property(nonatomic,copy)NSString * cp ...

  3. 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符

        入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...

  4. Java语言中的访问权限修饰符

    一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...

  5. 人工智能中小样本问题相关的系列模型演变及学习笔记(二):生成对抗网络 GAN

    [说在前面]本人博客新手一枚,象牙塔的老白,职业场的小白.以下内容仅为个人见解,欢迎批评指正,不喜勿喷![握手][握手] [再啰嗦一下]本文衔接上一个随笔:人工智能中小样本问题相关的系列模型演变及学习 ...

  6. 正则表达式preg_replace中危险的/e修饰符带来的安全漏洞问题

    mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) /e 修饰符使 preg_rep ...

  7. C#中的默认访问修饰符

    1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以访问该类型或成员.internal : 同一程序集中的任何代码都可以访问该类型或成员,但 ...

  8. JAVA中静态修饰符static的学习(初学)

    静态修饰符static,用于修饰类中的成员变量和成员函数. 用static修饰的成员变量也可叫做类变量. 什么时候使用静态 什么时候定义静态成员变量?     当对象中出现共享数据时,将该数据定义为静 ...

  9. 理解C语言中几个常见修饰符

    写在前面 今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感.做C语言开发时间也不短了,不过好 ...

随机推荐

  1. 【开发软件】推荐一款MAC OS X 下php集成开发环境mamp

      这里给大家推荐一款在mac上搭建WEB服务器环境的集成环境安装软件,非常的好用,需要的朋友可以拿去,不用谢 ^_^   之前苦于mac上搭建本地服务器之艰辛,找寻好久都没找到一款类似windows ...

  2. codis集群安装

    在网上找了很多codis的集群安装方法,看起来都是大同小异,本人结合了大多种方法完成了一套自己使用的codis的集群安装,可以供大家学习使用,如果有什么问题或者不懂的地方欢迎指正 1.集群规划: 三台 ...

  3. GeoEvent使用问题及解决方法整理

    假如GeoEvent的部署环境是一个典型的WebGIS架构(Portal+GIS Server),往往会遇到一些问题,例如: 问题:发布的StreamService流服务无法查看. 原因:默认发布的S ...

  4. iOS屏幕尺寸和分辨率了解

    1.截至目前为止,主流的iOS设备屏幕有以下几种: ---------------  iPhone  ---------- --------  iPad ------------ 2.iOS设备屏幕分 ...

  5. javascript 实现des解密加密

    //Paul Tero, July 2001 //http://www.tero.co.uk/des/ // //Optimised for performance with large blocks ...

  6. React Native开发入门

    目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料   一.前言 虽然只是简单的了解了一下Reac ...

  7. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  8. Java Serializable系列化与反系列化

    [引言] 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接 ...

  9. 专用服务器模式&共享服务器模式

    连接ORACLE服务器一般有两种方式:专用服务器连接(dedicated server)和共享服务器连接(shared server).那么两者有啥区别和不同呢?下面我们将对这两者的区别与不同一一剖析 ...

  10. ORA-00824: cannot set sga_target due to existing internal settings, see alert log for more information

    这篇文章是上篇文章”Expdp 导数错误 ORA-00832”的延续,前几天工作比较忙.累,直到今天才整理发出来.这个数据库实例的参数设置比较诡异其实是有原因的,由于这台数据库服务器系统是32位,数据 ...