Objective C中的ARC的修饰符的使用---- 学习笔记九
#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的修饰符的使用---- 学习笔记九的更多相关文章
- Java 中的 protected 访问修饰符你真的了解吗?
protected Java 中的 protected 访问修饰符 总结 在同一个包中,类中 protected 或 default 修饰的属性或方法可以在类外被其对象 (实例) 外部访问,也可以被子 ...
- iOS中copy和strong修饰符的区别
iOS中copy和strong修饰符的区别 //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错 @property(nonatomic,copy)NSString * cp ...
- 《挑战30天C++入门极限》入门教程:C++中的const限定修饰符
入门教程:C++中的const限定修饰符 const修饰符可以把对象转变成常数对象,什么意思呢? 意思就是说利用const进行修饰的变量的值在程序的任意位置将不能再被修改,就如同常数一样使用! ...
- Java语言中的访问权限修饰符
一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...
- 人工智能中小样本问题相关的系列模型演变及学习笔记(二):生成对抗网络 GAN
[说在前面]本人博客新手一枚,象牙塔的老白,职业场的小白.以下内容仅为个人见解,欢迎批评指正,不喜勿喷![握手][握手] [再啰嗦一下]本文衔接上一个随笔:人工智能中小样本问题相关的系列模型演变及学习 ...
- 正则表达式preg_replace中危险的/e修饰符带来的安全漏洞问题
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) /e 修饰符使 preg_rep ...
- C#中的默认访问修饰符
1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以访问该类型或成员.internal : 同一程序集中的任何代码都可以访问该类型或成员,但 ...
- JAVA中静态修饰符static的学习(初学)
静态修饰符static,用于修饰类中的成员变量和成员函数. 用static修饰的成员变量也可叫做类变量. 什么时候使用静态 什么时候定义静态成员变量? 当对象中出现共享数据时,将该数据定义为静 ...
- 理解C语言中几个常见修饰符
写在前面 今天下午一个同事问「register」关键字是什么作用?噢,你说的是「register」啊,它的作用是……脑袋突然断片儿,我擦,啥意思来着,这么熟悉的陌生感.做C语言开发时间也不短了,不过好 ...
随机推荐
- 【夯实PHP基础】PHP 面向对象
1. 对象中的属性或者函数是 private 或者是 protect的时候,当实例化这个对象的时候,外部是不能访问到这个属性和函数的. <?php class TestClass { //pri ...
- CSS:CSS使用Tips
Css是前端开发中效果展现的主要部分之一,良好的Css书写习惯可以为实际的项目开发提高效率,也可以为实现良好的团队合作提供保证. 一般新手在使用Css的时候经常会犯一些错误,出现一些不经意的漏洞,如果 ...
- javascript封装与多态的体现
封装是实现面向对象程序设计的第一步,封装就是将数据与函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型. 在传统的面向对象语言中有访问修饰符,如Private:只有类本身能 ...
- [JS]笔记13之Date对象
-->获取与设置时间的方法-->使用Date对象制作相应的效果 1.设置时间创建一个时间对象 new Date(time); 设置时间 time 从1970年1月1日至几种格式:new D ...
- H5学习
1.html{font-size:62.5%;}//不用font-size:10px的原因:(因为设了62.5%后就有1rem = 10px,便于用rem来指定元素的尺寸,这样响应式的时候可以直接改变 ...
- 深入理解Javascript--作用域和赋值操作
作用域作为一个最基础的功能存在于各种编程语言中,它使得我们的编程更加灵活有趣.其基础功能就是存储变量中的值,然后可以对值进行访问和修改. 可能我们都知道作用域的一些概念,以及其一些扩展的一些内容闭包等 ...
- Sass-也许你想和CSS玩耍起来(下篇)
问心无愧,共勉! sass-也许你想和CSS玩耍起来(上篇) 上篇中主要介绍了一些sass的基本特性.下篇中,主要是写一些我们常用的sass控制命令,函数和规则. sass进阶 控制命令 可能看过上篇 ...
- ae arcgis engine 关于面转线的方法和注意事项
代码很简单,如下 private void barButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs ...
- 自己写一个 jQuery 插件
我知道这一天终将会到来,现在,它来了. 需求 开发 SharePoint 的 CSOM 应用时,经常需要在网页上输出一些信息. 这种需求和 alert 的弹窗.F12 的断点查看信息的场景是不一样的: ...
- SharePoint 2013 必备组件之 Windows Server AppFabric 安装错误
1.如下图,在使用SharePoint2013产品准备工具的时候,网上下载安装Windows Server AppFabric的时候,报错,点击完成重启计算机,重新安装依然报错. 2.无奈之下,只有选 ...