#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. C++11之for循环的新用法

    C++使用如下方法遍历一个容器: #include "stdafx.h" #include<iostream> #include<vector> int m ...

  2. 解决WIN7与虚拟机CentOS的文件夹共享问题

    一.系统与软件 WIN7 64bit.VirtualBox 5.0.14.CentOS 6.5.SecureCRT 7.2.3 二.使用文件夹共享需要安装增强功能,但是安装时无法读取光盘iso文件 三 ...

  3. logstash VS splunk

    web 系统是典型的分布式部署,由此对其运行状况,硬件运转情况监控也显得尤为重要,这些监控数据表面上对业务运行没有多大的用处(属于基础数据),但正是这些基础数据形成了业务“流”.比如,用户搜索爱好,浏 ...

  4. 深入理解Javascript中构造函数和原型对象的区别

    在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...

  5. php文件之间传值的三种主流并且常用的方式

    一.表单传值 在<form>中的action填入要跳转页面的路径,method填入POST或者GET方法.表单中的提交按钮按下后,就会把<form>中有value都传到要跳转的 ...

  6. 在SharePoint中创建可自定义属性的文件夹

    概况 阅读时间:约5分钟 适用版本:SharePoint Server 2010及以上 面向用户:普通用户.管理员.开发人员 难度指数:★★★☆☆ SharePoint中的文件夹分为2种,一种是文档库 ...

  7. Linux系统NFS网络文件系统

    Linux系统NFS网络文件系统 NFS(network file system)网络文件系统,就是通过网络让不同的主机系统之间可以共享文件或目录,此种方法NFS客户端使用挂载的方式让共享文件或目录到 ...

  8. DVWA安装,ALMP环境搭建以及php版本转换

    前言 本文记录DVWA(Damn Vulberability Web App)在虚拟机中安装配置,包括ALMP环境的搭建和php版本的转换. 目录 2. ALMP环境搭建 3. php版本切换 一. ...

  9. childViewController 小计

    设置childViewcontroller Unbalanced calls to begin/end appearance transitions for 以上报错 需要添加 transitionF ...

  10. 记录一次Quartz2D学习(一)

    经常看点 drawRect的重写  但是不知道这究竟是神马 今天开始学习这一块的东西,更确切地说是深入 早在view的时候 就经常会调用layer的maskToBounds属性,其实 重写 drawR ...