`
ytwhw
  • 浏览: 98139 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

【转】nonatomic, retain,weak,strong用法详解

阅读更多

http://blog.csdn.net/dong_007_007/article/details/7722196

strong weak

strong与weak是由ARC新引入的对象变量属性
ARC引入了新的对象的新生命周期限定,即零弱引用。如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自动设置为nil。
@property(strong) MyClass *myObject;
相当于@property(retain) MyClass *myObject;
@property(weak) MyOtherClass *delegate;
相当于@property(assign) MyOtherClass *delegate;
强引用与弱引用的广义区别:
  强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。
  弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。没办法,还是 “强哥” 有面子。
简单讲strong等同retain
weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。
__weak, __strong 用来修饰变量,此外还有 __unsafe_unretained, __autoreleasing 都是用来修饰变量的。
__strong 是缺省的关键词。
__weak 声明了一个可以自动 nil 化的弱引用。
__unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
__autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。

之前写一个基于地理位置应用程序的时候无法让应用程序打开定位功能,在.h文件里面,我定义的属性是这样的:

 

@property(weak, nonatomic) CLLocationManager *locationManager;
后来,我将上面这句话改为:

@property(nonatomic, retain) CLLocationManager *locationManager;


就可以了。

接下来,就详细得介绍一下nonatomic, retain,weak,strong
在我们开发iOS程序时,常常会遇到:
property 和synthesize,以前很懒没有仔细去理解,只是看了看别人写的书,觉得挺容易的(在这里我不得不说,现在很多本土出的土书,尤其是早期的2009年,写的是真乱,误人子弟),所以今天有时间,自己试验了一番,希望和大家讨论。property,他可以提供的功能有:提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境 )。property不但可以在interface,在协议[url=]protocol[/url] .和类别[url=]category[/url]中也可以使用.synthesize的理解是:实现property所声明的方法的定义。其实说直白就像是:property声明了一些成员变量的访问方法 ,synthesize则定义了由property声明的方法。他们之前的对应关系是  property 声明方法 ----------》 头文件中申明的方法 synthesize定义方法---------》Cpp文件中定义的方法
不过这里还有有一点细微的差别,后面我会讲到。
先讲property大家都知道:@property(attribute1 , attribute2, ...])是@property的他的官方表达方式,所以看到attribute1, attribute2,你就应该懂的, 他的用法不是很简单。下面就对他的属性列表进行分类介绍:下面对属性列表进行一下简单的介绍,后续会用代码来解释。1.可读性:readonly 、readwrite@property(readwrite,....) valueType value;这个属性是变量的默认属性,就是如果你(readwrite and readonly都没有使用,那么你的变量就是readwrite属性),通过加入readwrite属性你的变量就会有get方法,和set方法。property(readonly,...) valueType value;这个属性变量就是表明变量只有可读方法,也就是说,你只能使用它的get方法。2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级.所以 不加nonatomic对与多线程是安全的 。 
其实他们都可以用代码表示:1.nonatomic 和 atomic@property(nonatomic ) NSObject* test1;
@synthesize test1;上面两句代码,表示我们对test1的访问,是非多线程安全的。@property(atomic) NSObject* test1;
@synthesize test1;上面两句代码,表示我们对test1的访问,是多线程安全的。其实也就是在讲该成员变量放到互斥代码中,例如,下面进行加锁。[_internal lock]; // lock using an object-level lock 
id result = [[value retain] autorelease]; 
[_internal unlock]; 
return result;

就如上面所说 ,这两个属性,是出于对多线程条件下 ,对test1的访问安全。如果你的程序的成员变量不存在安全问题,用nonatomic 就好,因为这样不要在访问是进行互斥,效率更高。
2. readonly 、readwrite (注,后续过程我们都会加入nonatomic 属性,因为它是十分普遍的)2.1 readonly@property(nonatomic  ,readonly) NSObject* test1;
@synthesize test1;上面的两句代码,objc编辑器将会为我们翻译为:@property(nonatomic  ,readonly) NSObject* test1; 等同-(NSObject*)test1;
@synthesize test1;等同-(NSObject*)test1{ return test1;}2.2 readwrite 
@property(nonatomic  ,readwrite ) NSObject* test1;
@synthesize test1;上面的两句代码,objc编辑器将会为我们翻译为:@property(nonatomic  ,readwrite ) NSObject* test1; 等同-(NSObject*)test1;

 
 

-(void)settest1(NSObject* other);@synthesize test1;等同-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{ test1 = other;}

这里要说明一下,
readonly 、readwrite 这两个属性他们的真正价值,不是提供成员变量访问接口,而是控制
 

成员变量的访问权限。所以要抓住他们真正价值。3. assign@property(nonatomic  ,assign) NSObject* test1;@synthesize test1;上面两句:objc编辑器将会翻译如下:@property(nonatomic  ,assign) NSObject* test1;等同

 
 

-(void)settest1(NSObject* other);@synthesize test1;-(void)settest1(NSObject* other);等同
{ test1 = other;}
4. retain@property(nonatomic  ,retain) NSObject* test1;
@synthesize test1;

objc编辑器翻译如:
 

@property(nonatomic  ,retain) NSObject* test1;等同-(NSObject*)test1;
-(void)settest1(NSObject* other);

@synthesize test1;


-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other) {    if (test1!= other)    {                   [test1release];                   test1= [otherretain];     }}
5. copy@property(nonatomic  ,copy) NSObject* test1;
@synthesize test1;

objc编辑器将翻译如:
 

@property(nonatomic  ,copy) NSObject* test1;
-(NSObject*)test1;
-(void)settest1(NSObject* other);

@synthesize test1;
 

-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{

    if (test1!=other) { 
        [test1release]; 
        test1= [othercopy]; 
    }
 

}对于Copy属性有一点要主要,被定义有copy属性的对象必须要符合NSCopying协议,并且你还必须实现了-(id)copyWithZoneNSZone*)zone该方法

 


代码才是王道:都是一些简单代码用例//为了更具有普遍性,我选择用自定义对象testObj /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .h
@interface testObj : NSObject<NSCopying>{
    
}
@end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .m-(id)copyWithZoneNSZone *)zone
{
    testObj* pObj = [[testObj allocWithZone:zone] init];
    return pObj;
}
@end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////testApp是包含多个testObj 对象指针//testApp .h
@interface testApp :
{
    testObj*  test1;
    testObj*  _test2;
}

@property(nonatomic , retain) NSObject* test1;
@property(nonatomic , copy) NSObject* test2;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testApp.m@synthesize test1;@synthesize test2 = _test2;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@synthesize test2 = _test2; //对这里要特别主要一下,这里可以看作是一种别名机制,这点和前面类比的C++头文件和Cpp文件不同。
例如对于setter函数,objc编辑器将会按如下方式翻译如果是@synthesize _test2;setter函数将是这种形式:-(void)set_test2(NSObject*); //注意中间的下划线写成@synthesize test = _test2;setter函数将是这种形式:
-(void)settest2(NSObject*);// _test2 被 test2替换了
可以看出这种别名机制,感觉是规范书写(其实更像是规范Objc的书写,大家可以看看官方文档中,成员变量都是前面带下滑线的(如_test2),所以才搞了这样一个别名规范代码中的书写)
//下面是一个功能函数,-(void )test{test1 = [[testObj alloc]init];// test1  retainCount  =1;

//下面有三种对test2操作方法: _test2 = test1; //这里是将test1的指针赋值给_test2指针,注意,并没有调用test2的setter方法 ,所以test retainCount  = 1、 test2 retainCount  = 0; self.test2 = test1;  //这里调用test2的Copy方法,因此这是test retainCount  = 1、 test2 retainCount  = 1;   test2   = test1; //这段代码系统将会提示出错说test2没有定义。因为这里编译器认为是一条赋值表达式,将test2看作是一个成员变量,而在我们的testApp 中是没有这个成员变量的,这里要区别我们所说的别名,别名机制可以看作是在调用setter或者getter函数才会起作用,而这里只是一个简单的赋值,也就出现未定义的错误。如果没有理解,你就记住要调用setter或者getter函数,就用"self.成员变量"这种形式就行了.
//我们把  test2   = test1这行代码注释掉,保证程序继续执行    [test1 release];  // 释放test1 ,test1 retainCount  = 0;
    
    [test2 release]; // 释放test2 ,test2 retainCount  = 0;
}@end

分享到:
评论

相关推荐

    IOS中(assign,retain,copy,weak,strong)的区别以及nonatomic的含义

    IOS中(assign,retain,copy,weak,strong)的区别以及nonatomic的含义 我们在声明@property 属性时,总是要在括号中写上assign、retain、copy、weak、strong中的一个,很多时候,我们仅仅只是按照习惯去写经常写...

    Ios retain assign区别

    本文将详细解释`retain`和`assign`的区别,以及其他相关的属性修饰符如`readonly`、`readwrite`、`nonatomic`等,帮助读者更好地理解这些关键字的作用及其应用场景。 #### `retain`与`assign` **1. `retain`** - *...

    ios_assign,retain和copy详解

    当属性被声明为retain时,在setter方法中会先释放旧值,然后对新值进行retain,再将其赋给成员变量。这样可以确保新值被保持,旧值被适当地释放。这是对象所有权的一种转移,即新的所有者必须负责后续的释放。例如:...

    分页效果设置

    @protocol ZSegmentedControlDelegate ...@property (nonatomic, weak)id &lt;ZSegmentedControlDelegate&gt; delegate; //@property (nonatomic, copy) void (^indexChangeBlock)(NSUInteger index);

    购物车Demo

    @property (nonatomic, strong) NSString *name; @property (nonatomic, assign) float price; @property (nonatomic, assign) NSInteger quantity; @property (nonatomic, assign) BOOL isSelected; @end @...

    ios-一款可以自定义的segmented control.zip

    自定义属性有: @property (nonatomic , strong) NSArray *btnTitleArray; @property (nonatomic , strong) UIColor *btnTitleNormalColor; @property (nonatomic , strong) UIColor *btnTitleSelectColor; @...

    UITableView、UITableView基本用法、UITableView详解

    iOS 开发中 UITableView 的使用详解 UITableView 是 iOS 开发中最常用的控件之一,用于显示列表数据。它类似于 Android 中的 ListView,都是用于显示列表数据的控件。在 iOS 开发中,UITableView 是一个非常重要的...

    retain和copy还有assign的区别

    ### retain、copy与assign的区别详解 #### 一、前言 在Objective-C中,了解`retain`、`copy`和`assign`这三个属性对于管理内存至关重要。这些属性主要用于定义对象属性时,它们决定了如何处理对象的引用。本文将...

    05-图片浏览器.zip

    @property (nonatomic, strong) NSArray *imageArray; // 图像控件 @property (weak, nonatomic) IBOutlet UIImageView *imageView; // 图像描述 @property (weak, nonatomic) IBOutlet UILabel *dscView; // 上...

    Objective-c解析XML封装

    @property (nonatomic, retain) NSMutableString *currentResult; @property (nonatomic, retain) NSMutableDictionary *map; @property (nonatomic, retain) NSMutableArray *list; -(NSMutableDictionary *)...

    JSON到NSObject的映射库Motis.zip

    Motis 使用 Cocoa 的 KVC 实现了智能的 JSON 到 NSObject 对象的映射。 示例代码: // --- User.h --- // @interface User : NSObject @property (nonatomic, strong) NSString *name; @property ...

    DynamicTableGenerator-iOS:一个 SettingsData Entry 表单自动生成工具

    #### ###对象/表单设置 @interface TestObject : NSObject@property ( nonatomic , retain ) NSDate * birth_date__dtd;@property ( nonatomic , retain ) NSString * first_name;@property ( nonatomic , retain )...

    LHDTableVIew简单封装

    #import "LHDBaseTableViewCell.h" @interface ...@property (nonatomic, strong) LHDBaseTableViewCell *myTableViewCell; @property (nonatomic, strong) NSArray *dataArray; - (void)resetDelegate;

    详解iOS App中UITableView的创建与内容刷新

    UITableView几乎是iOS开发中用处最广的一个控件,当然也是要记相当多东西的一个控件。 创建 首先创建一个新的项目,并添加一个MainViewController的Class文件 ...@property (nonatomic, retain) UITabl

    复杂XML的解析及组装

    @property(nonatomic,retain)NSMutableDictionary *attributes;//属性 @property(nonatomic,retain)NSMutableArray *childs;//下级子节点 @property(nonatomic,retain)NSString *name;//节点名称 @property...

    YYModel的具体用法

    在本文件中,我们将深入探讨YYModel的使用方法及其核心特性。 首先,YYModel的优势在于其性能。相比于其他类似库如Mantle或JSONModel,YYModel在解析速度上表现出色,这得益于它的底层优化,包括使用运行时方法和...

    XYChart:XYChart专为折线图和条形图设计,可以比较表单样式中的多个数据,并限制要显示的值的范围,等等。

    XYChart用于折线图和条形图,可以比较表单样式中的多个数据,并限制要显示的值的范围,等等。 线图 条形图 折线图中的单个数据 ...@property ( nonatomic , weak , nullable ) id &lt;XYChartDelegate&gt; delega

    Cocoa和CocoaTouch的模型框架Mantle.zip

    @property (readonly, nonatomic, strong) NSDate *createdAt; @property (readonly, nonatomic, assign, getter = isMeUser) BOOL meUser; @property (readonly, nonatomic, strong) XYHelper ...

    iOS字典转模型(双模型)方法一

    标题:“iOS字典转模型(双模型)方法一” 首先,我们需要理解什么是字典转模型。在Objective-C或Swift中,我们可以使用如Mantle、 ObjectMapper 或者苹果原生的 `NSKeyedUnarchiver` 进行字典到模型的转换。在这里...

Global site tag (gtag.js) - Google Analytics