iOS开发中各种关键字的区别

一、一些概念

  • 浅Copy:指针的复制,只是多了一个指向这块内存的指针,共用一块内存。
  • 深Copy:内存的复制,两块内存是完全不同的,

也就是两个对象指针分别指向不同的内存,互不干涉。

atomic是Objc使用的一种线程保护技术,

  • 基本上来讲,是防止在写未完成的时候被另外一个线程读取,
  • 造成数据错误。而这种机制是耗费系统资源的,

所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

二、各种属性的解析

weak:

<修饰Object类型,ARC下修饰delegate属性>

1.在ARC环境下,所有指向这个对象的weak指针都将被置为nil。

这个特性很有用,很多codeer都有被指针指向已释放的对象所造成的EXC_BAD_ACCESS困扰过,使用ARC以后,不论是strong还是weak类型的指针,都不会再指向一个已经销毁的对象,从根本上解决了意外释放导致的crash。

2.修饰Object类型,修饰的对象在释放后,指针地址会被置为nil,是一种弱引用。在ARC环境下,为避免循环引用,往往会把delegate属性用weak修饰;在MRC下使用assign修饰。weak和strong不同的是:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使还有weak型指针指向它,那么这些weak型指针也将被清除。

assign:

< 用于非指针变量。用于基础数据类型 (例如NSInteger)和C数据类型(int, float, double, char, 等),另外还有id >

1.用于对基本数据类型进行复制操作,不更改引用计数。也可以用来修饰对象,但是,被assign修饰的对象在释放后,指针的地址还是存在的,也就是说指针并没有被置为nil,成为野指针。如果后续在分配对象到堆上的某块内存时,正好分到这块地址,程序就会crash。之所以可以修饰基本数据类型,因为基本数据类型一般分配在栈上,栈的内存会由系统自动处理,不会造成野指针。

我们常见的id delegate往往是用assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a, 如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。因为循环引用而产生的内存泄露也是Instrument无法发现的,所以要特别小心。

copy:

修饰NSString、NSArray、NSDictionary等有对应可变类型的对象

建立一个索引计数为1的对象,然后释放旧对象。

是内容拷贝,会在内存里拷贝一份对象,两个指针指向不同的内存地址。一般用来修饰NSString、NSArray等有对应可变类型的对象,因为他们有可能和对应的可变类型(NSMutableString)之间进行赋值操作,为确保对象中的字符串不被修改 ,应该在设置属性是拷贝一份。而若用strong修饰,如果对象在外部被修改了,会影响到属性。

在不可变对象之间进行转换,strong与copy作用是一样的,但是如果在不可变与可变之间进行操作,我比较推荐copy,这也就是为什么很多地方用copy,而不是strong修饰NSString,NSArray等存在对应不可变类型的对象了,避免出现意外的数据操作.

strong

ARC下的strong等同于MRC下的retain都会把对象引用计数加1。

1.在ARC环境下,只要某一对象被一个strong指针指向,该对象就不会被销毁。如果对象没有被任何strong指针指向,那么就会被销毁。在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上跟MRC下得retain是比较相似的

retain

释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1

在MRC中,你需要自己retain一个想要保持的对象,ARC环境下就不需要了。现在唯一要做的就是用一个指针指向这个对象,只要指针没有被重置为空,对象就会一直在堆上。当指针指向新值的时候,原来的对象就会被release一次。这对实例变量,sunthesize的变量或者是局部变量都是实用的。

三、属性之间区别

在iOS开发中我们知道一般nsstring,就用copy,定义一个模型对象,就用strong,只是赋值的,例如int、double、char 以及CGRect类似的就用assign。但具体为什么可能很多人不是很清楚。

这里进行简单的解释:

  • 这些关键字基本上是针对属性的set方法。
  • 当用copy时,set方法会先release旧值,再copy一个新的对象,reference count 为1(减少了对上下文的依赖);当用assign,直接赋值,无retain操作。当用retain,release旧值,retain新值;

strong与weak的区别

  • strong类似于retain,会将对象的引用计数器+1,分配内存地址。
  • weak类似于指针,只是单纯的指向某个地址,但是本身并未分配内存地址。当指向的地址被销毁时,该指针会自动nil。

例子:

  • @synthesize string1;
  • @synthesize string2;

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


  1. self.string1 = [[NSString alloc] initWithUTF8String:"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。这样的好处能有效的防止野指针。在c/c++开发过程中,指针的空间释放了后,都要将指针赋为NULL. 在这儿用weak关键字做了这一步。

assign和weak的区别

  • 对于assign来说,一是非指针变量,比如说NSInteger之类的基础数据类型、C数据类型,还有就是避免出现循环引用的时候,
  • 对于weak,其和assign差不多,但是它多了一点,就是,它会自动对该类型变量设置为nil。 
  • 原文发布时间为:2017-10-20 
  • 本文作者:佚名
  • 本文来自合作伙伴“51CTO”,了解相关信息可以关注。
时间: 2024-12-07 22:44:20

iOS开发中各种关键字的区别的相关文章

iOS开发中使用UIScrollView实现无限循环的图片浏览器_IOS

一.概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件都介绍一遍确实没有必要,所谓授人以鱼不如授人以渔,这里会尽可能让大家明白其中的原理,找一些典型的控件进行说明,这样一来大家就可以触类旁通.今天我们主要来看一下UIScrollView的内容: UIView UIScrollView 实战--图片浏览器 二.UIView 在熟悉UIScrollView之前很有必要说一下UIView的内容.

iOS开发中的单元测试(一) 对比OCUnit和GHUnit

本文不讨论单元测试是什么,或者它之于一个工程的利弊,我认为单元测试是一个开发者保证产出代码质 量的有效工具.本文从使用者的角度对比当下比较流行的两款单元测试框架,给大家提供一些选用建议.如果 你还不甚了解单元测试在工程中所起到的作用,或者还不知道TDD的开发模式,可参考:Test-Driven Development和Unit Testing. 本文对比两个iOS开发中常见的单元测试框架:OCUnit,被官方集成进XCode 4.x版本中:GHUnit,被推荐 最多的测试框架,带GUI界面.初窥

Git在iOS开发中的使用

原文出自标哥的技术博客:http://www.henishuo.com/git-use-inwork/ 请阅读原文!!! Git在iOS开发中的使用 在iOS开发中,很多公司对项目的版本控制管理都使用了git,当然也有部分公司使用的是svn.当年我最初接触的是svn,觉得使用起来挺方便的,但是每次切分支都需要下载一份新的代码起来,这实在太麻烦了,而且公司的网络下载一个项目的所有资源起来也有数百M,这还用工作么? 当年,第一次听说github的时候,就听说是使用git来管理的,可是那时的我感觉好复

[译]iOS 开发中使用 Swift 进行 iBeacons 交互指南

本文讲的是[译]iOS 开发中使用 Swift 进行 iBeacons 交互指南, 原文地址:A Guide to Interacting with iBeacons in iOS using Swift 原文作者:MATT NEDRICH 译文出自:掘金翻译计划 译者:lovelyCiTY 校对者:Gocy015.Danny1451 #iOS 开发中使用 Swift 进行 iBeacons 交互指南 我最近致力于研究一个关于 iBeacons 的 iOS 项目.本文中,我将全面的介绍如何使用 

总结iOS开发中的断点续传与实践_IOS

前言 断点续传概述 断点续传就是从文件上次中断的地方开始重新下载或上传数据,而不是从文件开头.(本文的断点续传仅涉及下载,上传不在讨论之内)当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会去重头下载,这样很浪费时间.所以项目中要实现大文件下载,断点续传功能就必不可少了.当然,断点续传有一种特殊的情况,就是 iOS 应用被用户 kill 掉或者应用 crash,要实现应用重启之后的断点续传.这种特殊情况是本文要解决的问题. 断点续传原理 要实现断点续传 , 服

iOS开发中常用的数学函数

iOS开发中常用的数学函数   /*---- 常用数学公式 ----*/ //指数运算 3^2 3^3 NSLog(@"结果 %.f", pow(3,2)); //result 9 NSLog(@"结果 %.f", pow(3,3)); //result 27 //开平方运算 NSLog(@"结果 %.f", sqrt(16)); //result 4 NSLog(@"结果 %.f", sqrt(81)); //result

ios开发中uiscrollview里嵌套一个uiscrollview

问题描述 ios开发中uiscrollview里嵌套一个uiscrollview ios开发中uiscrollview里嵌套一个uiscrollview 其中小得scrollview是一个用于放滚动图片的.大得scrollview是用于整个view滚动的..其中还有很多别的view譬如imageview等,现在遇到这样的问题:我滚动大得scrollview,放滚动图片的scroll不跟着动,就一直悬在固定的位置.求解 急呀 解决方案 如果小的uiscrollview是作为subview添加到外部

iOS开发中的单元测试(二) 让断言活泼起来的匹配引擎

上一篇文章简单介绍了OCUnit和GHUnit两款iOS开发中较为常见的单元测试框架,本文进一步介绍单元测试 中的另一利器--匹配引擎(Matcher Engine).匹配引擎可以替代断言方法,配合单元测试引擎使用,测试 用例可以更多样化,更细致. 传统断言提供的方法数量和功能都有限,以导读中提到的两款框架为例 ,即使是断言相对丰富的GHUnit也只是提供了38种断言方法,范围仅涵盖了逻辑比较,异常和出错等少数几方 面,仍然很单一.而使用匹配引擎代替断言,可能性就大大丰富了,除了普通断言支持的规

ios开发中时间转换的方法集锦

  这篇文章主要介绍了ios开发中时间转换的方法集锦,需要的朋友可以参考下 在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理. 例如: //实例化一个NSDateFormatter对象 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; //设定时间格式,这里可以设置成自己需要的格式 [dateFormatter setDateFormat:@"yy