当前位置: 首页 > 编程日记 > 正文

nonatomic, retain,weak,strong用法详解

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{
    
}
@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

转载于:https://www.cnblogs.com/mafeng/p/5231906.html

相关文章:

“ Error:(1, 1) java: 非法字符: ‘\ufeff‘ ”错误的解决方法

前言:今天为了做作业,在 github 上面下载了个项目,然后在运行项目时发现报错,在此记录一下 “ Error:(1, 1) java: 非法字符: ‘\ufeff’ ”错误的解决方法 发生原因 这个项目从目录的结构可以很明显地看出是使用 Eclipse 开发的…

2022-2028年中国钢铁电商产业竞争现状及发展前景预测报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新(交付时间约3个工作日) 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国钢铁电商行业市场行业相关概述、中国钢铁电商行业市场行业运行环境、分析了中国钢铁电商行…

java开发webservice的几种方式

为什么80%的码农都做不了架构师?>>> webservice的应用已经越来越广泛了,下面介绍几种在Java体系中开发webservice的方式,相当于做个记录。 1.Axis2 Axis是apache下一个开源的webservice开发组件,出现的算是比较早了&a…

改变gazebo背景颜色

修改这里:

【Unity教程】创建一个完整的驾驶游戏

专业游戏设计 你会学到什么 在unity HDRP创建一个完整的驾驶游戏 定制不同类型的汽车 将人工智能汽车和人工智能航路点系统添加到你的赛道上 添加汽车展厅菜单以解锁和购买新车 在Blender中设计自己的赛道 易于理解的编码使游戏工作 流派:电子学习| MP4 |视频:h264&#xff0c…

哈夫曼编译码器

前言:又到了学校一年一度的数据结构课设的日子,经不住学弟学妹热心地“询问”我数据结构课设的内容,我就在这里把我之前数据结构课设做的东西总结一下 哈夫曼编译码器 我课设选择的题目是哈夫曼编译码器,类似于我们平时用的解压缩…

Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

题意&#xff1a; 线段树做法 分析&#xff1a; 因为每次都是在当前位置的前缀区间查询最大值&#xff0c;所以可以直接用树状数组优化。比线段树快了12ms~ 代码&#xff1a; #include<cstdio> #include<cmath> #include<iostream> #include<algorithm>…

2022-2028年中国钢筘行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国钢筘行业市场行业相关概述、中国钢筘行业市场行业运行环境、分析了中国钢筘行业市场行业的…

控制台绘制正切曲线

前面介绍了&#xff1a;控制台绘制正弦/余弦曲线 , 控制台绘制正弦曲线和余弦曲线同时显示 下面来看看正切曲线吧&#xff0c;其实也都差不多…… #include <stdio.h> #include <math.h>int main() {double y;int x,k;for(y10;y>-10;y--){katan(y)*7;if(k>0)…

PX4多机ros仿真报错

出现报错&#xff1a; 缺少配置文件&#xff0c;需要添加路径到文件中&#xff1b; 在根目录下打开终端输入&#xff1a; 出现下面一个界面&#xff1a;&#xff08;蓝色是我添加的&#xff09; 保存退出&#xff1b; 重新进行刚开始的操作&#xff1a; 使用默认的.launc…

Unity创建2D动作RPG游戏 Create Action 2D RPG Game in Unity

在Unity中创建动作2D RPG游戏 大小解压后&#xff1a;5.69G 时长10h 包含 Udemy Game Asset.unitypackage 源文件 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 你会学到什么 学习基础来提升C#&#xff0c; 为远程和特殊攻击…

Nginx学习4:负载均衡实例

Nginx配置实例-负载均衡 目标 在浏览器地址栏输入地址 http://192.168.126.131:8080/edu/a.html&#xff0c;负载均衡效果&#xff0c;平均分配到 8080 和 8081 端口中 准备工作 &#xff08;1&#xff09;准备两台 tomcat 服务器&#xff0c;一台 8080&#xff0c;一台 80…

2016030204 - git和github结合

1.下载和安装git客户端 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5232291.html 2.github上创建项目 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5233495.html 3.密钥相关信息设置 参考&#xff1a;http://www.cnblogs.com/zhtzyh2012/p/5233630.html 4…

2022-2028年中国钢化玻璃行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国钢化玻璃行业市场行业相关概述、中国钢化玻璃行业市场行业运行环境、分析了中国钢化玻璃行…

nginx如何解决超长请求串

nginx是一个强大的http服务器&#xff0c;但是在使用过程中发现&#xff0c;当遇到超长的post请求或者get请求时&#xff0c;nginx会返回413、400、414等状态码&#xff0c;这是因为请求串长度超过了nginx默认的缓存大小或者请求串大小&#xff0c;那么我们需要怎么样来解决这些…

ubuntu安装qwt出现错误时"mkdir: 无法创建目录“/usr/local/qwt-6.1.3“: 权限不够"

报错&#xff1a; 在root用户下执行操作&#xff0c;参考链接安装qwt

Unity 2021人工智能导论 Introduction to Artificial Intelligence in Unity 2021

学习视频游戏开发中最常用的人工智能技术的基础知识。 你会学到什么 了解如何使用有限状态机 学习行为树的基础知识 了解如何实现阿斯塔寻路算法 了解如何在游戏中实现传感器 了解如何创建GOAP系统 了解植绒的基本知识 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频…

HikariPool 连接池问题

前言&#xff1a;今天在一个项目运行的时候发现一个很奇怪的问题&#xff0c;当我有一段时间无操作之后再进行插入操作的话&#xff0c;就会出现HikariPool相关的报错&#xff0c;在此记录一下 问题 2022-02-20 13:14:04.178 WARN 4012 --- [nio-8888-exec-6] com.zaxxer.hik…

谈谈对web标准的理解

Web标准不是某一个标准&#xff0c;而是由一系列标准组合而成。网页主要由三部分组成&#xff1a;结构、表现和行为。对应的标准也分三方面&#xff1a;结构化标准语言主要包括XHTML和HTML以及XML&#xff0c;表现标准语言主要包括CSS&#xff0c;行为标准主要包括对象模型&…

2022-2028年中国二次供水设备行业研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国二次供水设备行业市场行业相关概述、中国二次供水设备行业市场行业运行环境、分析了中国二…

linux磁盘配额管理

linux-用户磁盘配额磁盘配额就是管理员可以为用户所能使用的磁盘空间进行配额限制&#xff0c;每一用户只能使用最大配额范围内的磁盘空间磁盘配额可以限制指定账户能够使用的磁盘空间,这样可以避免因某个用户的过度使用磁盘空间造成其他用户无法正常工作甚至影响系统运行。在服…

终端打不开(右键和快捷键)?因为phthon?

参考连接&#xff1a;https://www.cnblogs.com/dolphi/p/3622570.html 在总的环境变量中删除掉LC_ALL这一项&#xff0c;重新启动后即可恢复以及打开终端&#xff1b; 具体怎么操作&#xff1a;是师兄帮弄的&#xff0c;没看清楚怎么操作&#xff01;

Unity从头到尾无代码游戏制作学习教程

制作没有代码的游戏 Unity中的主视觉脚本&#xff01; 流派:电子学习| MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;48.0 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:26.2 GB 含课程文件|时长:21小时 11分…

经常使用ARM汇编指令

一面学习&#xff0c;一面总结&#xff0c;一面记录。 以下是整理在网上找到的一些资料&#xff0c;简单整理记录一下&#xff0c;方便以后查阅。 ARM处理器的指令集能够分为跳转指令、数据处理指令、程序状态寄存器&#xff08;PSR&#xff09;处理指令、载入/存储指令、协处理…

解决 Could not autowire. No beans of ‘UserDao‘ type found 问题

前言&#xff1a;今天在完善项目的时候发现使用Autowired注入的Dao层依赖出现报错&#xff0c;但是不影响项目的运行&#xff0c;在此记录一下 问题 这个错误不影响项目运行&#xff0c;但是它看着很烦… 分析 Dao层代码&#xff1a; Mapper public interface UserDao {User…

2022-2028年中国二次供水产业发展动态及投资战略规划报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国二次供水行业市场行业相关概述、中国二次供水行业市场行业运行环境、分析了中国二次供水行…

Tomcat安全

一、版本安全 升级当前的tomcat版本为最新稳定版本。故名思议&#xff0c;最新稳定版本就要兼顾最新和稳定这两个概念。一个稳定的版本&#xff0c;是需要时间沉淀的&#xff0c;而最新又是相对于稳定版而言的最新。因此我们一般会选择当前大版本中&#xff0c;最新版本往前推几…

Linux系统下给Qt应用程序配置图标(其余的应用程序也是可以实现添加图标的)

添加链接描述1.创建启动脚本 打开终端输入&#xff1a; touch run.sh在/home目录下找到run.sh文件&#xff0c;双击打开编辑&#xff1b; #&#xff01;/bin/bash cd /execute/home/xxx/ &#xff03;/home/xxx/是Release编译以后生成的应用程序的路径 ./Json2.创建d…

Unity完全学习教程-从初学者到C#中的RPG游戏开发

打造3款游戏&学习Unity实用方式&#xff01;从基础开始&#xff0c;以一个RPG游戏结束。使用Unity 2020和C# 你会学到: 通过创建酷游戏的实用方法 游戏开发的基础和核心概念 创建一个拥有大量功能的角色扮演游戏 代码背后的数学解释。 要求 最基本的C#或其他面向对象语言…

2345电脑管家_极限挑战:同时安装4大国产杀毒软件,我的电脑是最安全的?

还没到国庆假期&#xff0c;老毛桃就提前给自己放了假&#xff0c;闲着就作妖&#xff0c;这不&#xff1f;现在就忙着卸载。人固有一秃&#xff0c;或秃于科研&#xff0c;或秃于卸载&#xff01;说到作妖&#xff0c;是怎么一回事呢&#xff1f;此前不少网友私信让老毛桃挑战…