Objective-c 的 内存管理和@property strong,weak,assign,copy,retain等关键字介绍

这篇博客介绍了Objective-C的内存管理机制,包括引用计数原则和对象生命周期。详细阐述了@property中strong, weak, assign, copy, retain等关键字的含义和应用场景,特别是retain、release、retainCount的实现原理。还提到了点语法、内存分布以及assign、weak、copy、nonatomic和__block等关键字的作用和区别。" 107938414,9393772,五节点Hadoop-2.6.0-cdh5.14.2 HA集群详细部署教程,"['Hadoop', '集群', '高可用', 'Zookeeper']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@property strong,weak,assign,copy,retain等关键字

内存管理

众所周知ios的内存管理是基于引用计数的。

  • 当对象被创建(通过alloc、new或copy等方法)时,其引用计数初始值为1
  • 給对象发送retain消息,其引用计数加1
  • 給对象发送release消息,其引用计数减1
  • 当对象引用计数归0时,ObjC給对象发送dealloc消息销毁对象

注意:

  1. 通过alloc、new或copy等方法引用计数初始值为1。而其他方法比如[NSMutaleArray array]返回时会自动加入autoreleasepool,arc中如果有强引用指向它,其引用计数为2.非arc时一般需要retain 一下,才能持有对象。
  2. alloc和new 的主要区别功能上几乎是一致的。new会默认使用init的初始化方法。其次只在于alloc分配内存的时候使用了zone,这个zone是个什么东东呢?它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提升了程序处理速度。
retain、release、retainCount 的实现

这三个参数是 __CFDoExternRefOperation(uintptr_t op,id obj)接口实现。这个接口首先会通过obj的地址作为键值。找到其引用计数的散列表。然后根据op的类型分别进行这三种操作。

@property介绍

OC意识到当getter方法和setter方法遇到一个类有大量的实例变量时,getter方法和setter方法的 声明和实现将会变的非常繁琐,这时OC就有了@property的产生。即当OC中使用@property时就同时声明了setter和getter方法。

关于点语法使用注意
格式:对象.属性名
1. 点语法是xcode的特性,xcode帮我们做了代码的替换,即p.age并不是直接访问实例变量,而是xcode看到点语法后,如果是设置值会自动帮我们替换成[p setAge:18],如果是取值会自动帮我们替换成[p age]
2. p.age到底是替换成get方法还是set方法,一般取决于p.age出现在等号的左侧还是右侧即是设置值还是取值。


内存分布
栈:存放的是局部变量,这块存储区域是系统管理的,不需要我们管理。
堆:存放的是OC中的对象,这块存储区域是程序员自己管理的。它是动态存储区域。
常量区:存放的是常量,这块存储区域是系统管理的。
全局区:存放的时全局变量和静态变量,这块存储区域是系统管理的。
代码区:存放分是代码,这块区域是系统管理的。
指针存放在栈中,而指针指向的变量是存放在堆中。
因此当指针被回收的时候,它的对象并不会被回收。


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


weak关键字
修饰Object类型,修饰的对象在释放后,指针地址会被置为nil,是一种弱引用。在ARC环境下,为避免循环引用,往往会把delegate属性用weak修饰;在MRC下使用assign修饰。weak和strong不同的是:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使还有weak型指针指向它,那么这些weak型指针也将被清除。
当retainCount=0时。->_onjc_rootDealloc->objc_dispos->objc_destructinstance->objc_clear_deallocating.
objc_clear_deallocating
1. 会从哈希表中获取以其对象地址为键值的记录。
2. 将记录中所有——weak修饰的变量地址至为nil。
3. 从weak表中删除其记录
4. 从引用计数表中删除其记录。


copy关键字
当属性是NSString数据类型的时候就使用copy
copy 此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝”。内存地址发生变化,此属性只对那些实行了NSCopying协议的对象类型有效。


retain 和strong 关键字
retain与strong相对应,使用了引用计数,retain+1,release -1;当引用 计数为0时,dealloc会被调用,内存被释放。retain对应mac,strong 对应arc。


nonatomic
指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定nonatomic,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了nonatomic,那么访问器只是简单地返回这个值。


__block
因为在MRC下,block在创建的时候,它的内存是分配在栈(stack)上的,而不是在堆(heap)上,可能被随时回收。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。通过copy可以把block拷贝(copy)到堆,保证block的声明域外使用。在ARC下写不写都行,编译器会自动对block进行copy操作。

__block与__weak的区别

__block:在ARC和MRC下都可用,可修饰对象,也可以修饰基本数据类型。

__block对象可以在block被重新赋值,__weak不可以。

__weak:只在ARC中使用,只能修饰对象,不能修饰基本数据类型(int、bool)。

同时,在ARC下,要避免block出现循环引用,经常会:__weak typedof(self) weakSelf = self;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值