objective-c中的特性

一,retain, copy, assign区别

概念: 
assign: 简单赋值,不更改索引计数(reference counting)。 
copy: 建立一个索引计数为1的对象,然后释放旧对象 
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

例:

1 NSString *pt = [[NSString alloc] initwithstring:@"abc"]; 

上面一段代码会执行以下两个动作 
1 在堆上分配一段内存用来存储@"abc"  比如:内存地址为:0x1111 内容为 "abc" 
2 在栈上分配一段内存用来存储pt  比如:地址为:0xaaaa 内容自然为0x1111   
下面分别看下assign retain copy 
assign的情况:NSString *newpt = [pt assign];     
此时newpt和pt完全相同 地址都是0xaaaa  内容为0x1111  即newpt只是pt的别名,对任何一个操作就等于对另一个操作。 因此retaincount不需要增加。 
retain的情况:NSString *newpt = [pt retain];     
此时newpt的地址不再为0xaaaa,可能为0xaabb 但是内容依然为0x1111。 因此newpt 和 pt 都可以管理"abc"所在的内存。因此 retaincount需要增加1   
copy的情况:NSString *newpt = [pt copy];   
此时会在堆上重新开辟一段内存存放@"abc" 比如0x1122 内容为@"abc 同时会在栈上为newpt分配空间 比如地址:0xaacc 内容为0x1122 因此retaincount增加1供newpt来管理0x1122这段内存 
  
理解: 
1,假设你用malloc 分配了一块内存,并把它的地址赋值给了指针a,   后来你希望指针b也共享这段内存,于是你又把a赋值给  (assign)了 b。此时a和b指向同一块内存,当a不需要使用这段内存时是不能直接释放它,因为a并不知道 b也在使用这块内存,如果 a释放了,那么b在使用这块内存的时候程序会crash掉 
2,为了解决1中的问题,最简单的一个方法就是使用引用计数,在上面的那个例子中,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到 2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候, 代表该内存不再被任何指针所引用,系统可以把它直接释放掉。 
3. 上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。 
4.copy是在你不希望a和b共享一块内存时会使用到。a和b各自有自己的内存。

总结: 
使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等) 
使用copy: 对NSString 
使用retain: 对其他NSObject和其子类

二,ios5中新加入RAC的strong,week,unsafe_unretained

说明: 
iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新关键字与assign类似)。在iOS5中用这些新的关键字,就可以不用手动管理内存了 
具体使用: 
strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切

1.    @property (nonatomic, strong) NSString *string1;   
    2.    @property (nonatomic, strong) NSString *string2;

// 附注:nonatomic关键字:

noatomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

有这样两个属性,

1.    @synthesize string1;   
    2.    @synthesize string2;

猜一下下面代码将输出什么结果?

1.    self.string1 = @"String 1";   
    2.    self.string2 = self.string1;   
    3.    self.string1 = nil;  
    4.    NSLog(@"String 2 = %@", self.string2);

结果是:String 2 = String 1

由于string2是strong定义的属性,所以引用计数+1,使得它们所指向的值都是@"String 1", 如果你对retain熟悉的话,这理解并不难。

接着我们来看weak关键字: 
如果这样声明两个属性:

1.    @property (nonatomic, strong) NSString *string1;   
    2.    @property (nonatomic, weak) NSString *string2;

并定义

1.    <pre name="code" class="cpp">@synthesize string1;   
    2.    @synthesize string2;

再来猜一下,下面输出是什么?

1.    self.string1 = @"String 1";   
    2.    self.string2 = self.string1;   
    3.    self.string1 = nil;  
    4.    NSLog(@"String 2 = %@", self.string2);

结果是:String 2 = null

分析一下,由于self.string1与self.string2指向同一地址,且string2没有retain内存地址,而self.string1=nil释放了内存,所以string1为nil。声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。

接着我们来看unsafe_unretained 
从名字可以看出,unretained且unsafe,由于是unretained所以与weak有点类似,但是它是unsafe的,什么是unsafe的呢,下面看实例。 
如果这样声明两个属性: 
并定义 
    1.    @property (nonatomic, strong) NSString *string1;   
    2.    @property (nonatomic, unsafe_unretained) NSString *string2;

再来猜一下,下面的代码会有什么结果? 
    1.    self.string1 = @"String 1";   
    2.    self.string2 = self.string1;   
    3.    self.string1 = nil;  
    4.    NSLog(@"String 2 = %@", self.string2);

请注意,在此我并没有叫你猜会有什么输出,因为根本不会有输出,你的程序会crash掉。

原因是什么,其实就是野指针造成的,所以野指针是可怕的。为何会造成野指针呢?同于用unsafe_unretained声明的指针,由于self.string1=nil已将内存释放掉了,但是string2并不知道已被释放了,所以是野指针。然后访问野指针的内存就造成crash.  所以尽量少用unsafe_unretained关键字。

strong,weak, unsafe_unretained往往都是用来声明属性的,如果想声明临时变量就得用__strong,  __weak, __unsafe_unretained,  __autoreleasing, 其用法与上面介绍的类似。 
还是看看实例吧。

1.    __strong NSString *yourString = @"Your String";   
    2.    __weak  NSString *myString = yourString;   
    3.    yourString = nil;   
    4.    __unsafe_unretained NSString *theirString = myString;  
    5.    //现在所有的指针都为nil

再看一个:

1.    __strong NSString *yourString = @"Your String";   
    2.    __weak  NSString *myString = yourString;   
    3.    __unsafe_unretained NSString *theirString = myString;  
    4.    yourString = nil;   
    5.    //现在yourString与myString的指针都为nil,而theirString不为nil,但是是野指针。

时间: 2024-10-18 16:33:48

objective-c中的特性的相关文章

java 对象的this使用 java方法中参数传递特性 方法的递归

一.this关键字,使用的情形,以及如何使用. 1.使用的情形 类中的方法体中使用this  --初始化该对象 类的构造器中使用this --引用,调用该方法的对象 2.不写this,调用 只要方法或者构造器中  不存在成员变量与局部变量同名的情况,可直接不写this 否则方法中或构造器中使用的就是局部变量 3.static 静态方法不能调用this,不能调用任何非static修饰的成员变量 或者方法 二.java方法中  参数传递特性 1.基本数据类型--实际是新增变量,并赋值而已   不过代

iOS开发——语法OC篇&amp;Objective-C新特性的总结

Objective-C新特性的总结 1.nonnull nonnull : 标示当前属性不为空,让外界放心用,只做标示用,即使为空,也木有办法    相当于swift里面的 ! 号 @property (nonnull, nonatomic, strong) NSString *name; 2.nullablenullable : 标示当前属性可能为空,让外界使用时注意    相当于swift里面的 ? 号 @property (nullable, nonatomic, strong) NSSt

PHP中面向对象特性实现

PHP近些年来成为全球最流行的网页编程语言,该语言以弱类型.易兼容.门槛低.开发快.功能强著称,且听别人这么说,我在有了c和c#基础后学习PHP过程中也并不是很顺利,该语言的一些特殊的语法规则又是让我混淆,不过不得不说,它让编程变得更加容易了.大家可能学习过C++或C#,应该知道面向对象的三大特征:封装性.继承性.多态性.其实任何一门编程语言,除了语言特有的API不同外,语言本身的编程思想和理念是想通的.现在,就让我带你走进PHP中面向对象特性的实现方式. 首先必须明白PHP为面向对象设定的6个

objective C中的字符串(三)

holydancer原创,如需转载,请在显要位置注明: 转自holydancer的CSDN专栏,原文地址:http://blog.csdn.net/holydancer/article/details/7343561 objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的操作字符串,下面举几个例子: 1.创建: 直接利用等号赋值 NSString *

C#中的 特性 详解(转载)

本篇幅转载于:http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html C#中特性详解 特性提供了功能强大的方法,用于将元数据或声明信息与代码(程序集.类型.方法.属性等)相关联.特性与程序实体关联后,即可在运行时使用"反射"的技术查询特性. 特性具有以下属性: 特性可向程序中添加元数据.元数据是有关在程序中定义的类型的信息.所有的 .NET 程序集都包含指定的一组元数据,这些元数据描述在程序集中定义的类型和类型成员.可

objective C中继承、协议、分类和多态的实现

第一.objective C中继承的实现 在oc中只有实例变量会有权限控制,实例方法和类方法是没有权限控制的,这点与c++不同,OC默认的是protected,并且在声明权限控制时,没有分号 在OC中可以像C++一样用指针运算法来访问实例变量 Rectangle.h 文件代码: #import <Foundation/Foundation.h> @interface Rectangle : NSObject { int _width; int _height; } @property (non

Performance Tuning guide 翻译 || Performance Tuning Guide 11G中新增特性

Performance Tuning Guide 11G中新增特性 本章描述了Oracle11g Release2(11.2)中增加了哪些新的性能调整 特性,以及指向这些增加信息. 本章节描述的特性以及增强,包含了优化数据库性能的各个方面. 关于Oracle11gR2的所有新特性汇总,可以查看Oracle Database New Features Guide. 11.2.0.2中新增的新特性(关于性能调优) 新增的以及更新过的性能调整特性包括: 注:Resource Manager(资源管理器

objective C中的字符串

holydancer原创,如需转载,请在显要位置注明: 转自holydancer的CSDN专栏,原文地址:http://blog.csdn.net/holydancer/article/details/7343561 objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的操作字符串,下面举几个例子: 1.创建: 直接利用等号赋值 NSString *

.net 4.0 中的特性总结(一):dynamic

在新版本的C#中,dynamic关键词是一个很重要的新特性,现在你可以创建动态对象并在运行时再决定它的类型.而且.net 4.0为CLR加入了一组为动态语言服务的运行时环境,称为DLR(Dynamic Language Runtime动态语言运行时),这使得: C#这种静态类型语言可以在 .NET Framework 中开发动态语言并为与其它动态语言提供互操作性了. DLR架构见下图: 例如: 执行结果:

&lt;转载&gt;C#中的特性(Attributes)

作者:sadaf alvi    阅读人次:7233    文章来源:CSDN Bolg    发布时间:2007-9-1 翻译不是为了翻译,是为了学习!因为只有翻译我才能逐句的看完整篇文章.当然还可以得到各位达人的斧正,让我由懂得皮毛到渐入佳境!乐哉,幸哉! 原文 约定: 1."attribute"和"attributes"均不翻译 2."property"译为"属性" 3.msdn中的原句不翻译 4."progr