Objective-C(十六、内存管理,自动释放池,ARC,强指针,弱指针,方法族)——iOS开发基础



结合之前的学习笔记以及参考《Objective-C编程全解(第三版)》,对Objective-C知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~



十六、内存管理相关知识(二)



1、autorelease,自动释放机制

- (instancetype)autorelease;

(1)自动释放池的创建

iOS5.0之前

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 //进行一系列操作
 //此处不可以使用break、return、goto之类的语句
 Person *p = [[[Person alloc] init] autorelease];
 [pool release];

iOS5.0之后

@autoreleasepool {
 //进行一系列操作
 //此处可以使用break、return、goto等语句
 //代码
 };

ARC中是禁用NSAutoreleasePool的,而是用新语法来进行操作,性能更好,效率更高。

(2)基本用法

a、会将调用autorelease方法的对象放入自动释放池中;

b、当pool销毁时,池中记录的所有对象都会被发送release消息

c、调用autorelease方法不影响引用计数器的计数值,返回对象本身;

(3)优缺点

优点:不必担心实例对象何时释放,不必担心何时调用release

缺点:不能精确控制对象释放时间;若为大型对象,应该使用完立即释放,否则会占用内存。

(4)存储方式

a、以栈的数据结构进行存储,释放时遵循先进后出

b、iOS程序运行过程中,允许创建多个pool,可以嵌套使用

 @autoreleasepool {
     @autoreleasepool {
         //XXXX
     }
 }

c、当一个实例对象调用aurelease方法时,会将此实例对象放入栈顶的自动释放池。

(5)在实际开发中,往往创建类方法快速创建对象

 + (id)person {
     return [[[self alloc] init] autorelease];
 }

注意:不指定类型,使用self,这样既可以实现父类对象创建,又可以实现子类对象创建

通常系统自带的方法中若不带alloc,new,copy关键字,说明返回的实例对象是经过了autorelease的,不需要再手动调用release



2、ARC:Automatic Reference Counting,自动引用计数

(1)基本特征

a、一种编译器特性,Xcode5.0以后创建的项目自动执行ARC机制;

b、编译器会根据赋值操作、变量的初始变化、变量的生命周期等因素,在释放的位置自动加入retain/release/autorelease相关的代码;

c、ARC只能管理OC对象,不能管理通过malloc申请的内存

(2)ARC判断对象是否应该释放的准则:

只要没有强指针指向此对象,就会被释放;

(3)注意要点:

a、ARC有效地程序中,不能调用与引用计数有关的方法retain,release,autorelease,retainCount

同时也不能那个使用这类函数的selector(@selector(retain));

b、可重写dealloc,但不能调用[super delloc]

c、@property相关参数修改

strong:成员变量为强指针类型,相当于MRC中的retain(使用于OC对象)

weak:弱指针类型,相当于MRC中的assign(使用于OC对象)

assign:非指针类型(适用于非OC对象)

unsafe_unretained:非nil化的弱指针

(4)循环引用:一端用strong,一端用weak



3、强指针,弱指针(强引用,弱引用)

(1)强指针:__strong,拥有所有权的指针

(2)弱指针:__weak,不会对对象的释放产生影响

a、为了避免循环引用,需要这类变量能够引用对象,但不会成为对象所有者,不影响对象本身的而回收

b、弱指针是通过存储一个指向对象的指针创建的,且不保留对象

c、弱引用情况下,无论对变量赋值或解除引用,变量的引用计数都不会发生变化;

(3)__unsafe_unretained:非nil化的弱指针,即当所指向的内存区域被释放了,这个指针就是一个野指针了;

a、跟字面意思一样,这种类型的变量时不安全的,野指针操作不当会造成严重后果;

b、有一些类的实例不能使用自动nil化的弱引用,需要使用__unsafe_unretained代替__weak

例如lion ReleaseNote中NSWindows、NSTextView、NSFont、NSImage等类的实例不能使用弱引用,不过未来是否支持,或者当前可自动nil化的未来是否继续支持不得而知。

使用时将上述修饰词加在对象前

例如: __unsafe_unretained Person* p;



4、弱指针的自动nil化

弱指针会在其指向的实例对象被释放后自动变成nil;

即当弱指针指向的实例对象被释放了,弱指针也不会变成野指针



5、方法族:同对象生成相关的方法集合

需要满足以下命名规则(必须遵守,否则ARC可能不会释放对象,造成内存泄露)

——选择器同方法族名相同(开头的_可忽略),或选择器的名字由方法族名加上非小写字母开头的字符串构成

例如

 init
 initWithName:
 initToMemory
 _init:locale

错误:

 initialize     init后面不可接小写字母
 initwithName   init后面不可接小写字母
 do_init        不以init开头

目前OC有5个方法族

 alloc方法族
 copy方法族
 mutableCopy方法族
 new方法族   以上4种以其开头的方法表示调用者对被创建的对象拥有所有权,返回的对象必须是可以被retain的
 init方法族

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-24 02:15:18

Objective-C(十六、内存管理,自动释放池,ARC,强指针,弱指针,方法族)——iOS开发基础的相关文章

OC 内存泄露 自动释放池

有这么一段代码:largeNumber可以当做一个很大的数 花絮:看到下面的代码就想起这么一个笑话: 一个老程序员,功成名就,金盆洗手不在写代码后,决定练练书法.提笔思索良久后在纸上写下:Hello world! for (int i = 0 ; i < largeNumber; i++) { NSString *myStr = @"Hello world"; // 原谅我用Hello world myStr = [myStr stringByAppendingString:[N

Objective-C(8)内存管理之自动释放池

自动释放池 是一种半自动的内存管理方式 autorealease方法: - (instancetype)autorelease 此方法将对象放到自动释放池中,当自动释放池销毁时,池中的所有对象都会随之销毁. 常见的使用方式: Person *p = [[[Perosn alloc] init] autorelease]; 使用@autoreleasepool关键字来使用自动释放池 其后的{-}相当于自动释放池的生存期 ,如: @autoreleasepool {      Person *p =

关于自动释放池的讲解与介绍

由于 Objective-C 中的内存管理是一个比较大的话题,所以会分为两篇文章来对内存管理中的一些机制进行剖析,一部分分析自动释放池以及 autorelease 方法,另一部分分析 retain.release 方法的实现以及自动引用计数. 写在前面 这篇文章会在源代码层面介绍 Objective-C 中自动释放池,以及方法的 autorelease 的具体实现. 从 main 函数开始 main 函数可以说是在整个 iOS 开发中非常不起眼的一个函数,它很好地隐藏在 Supporting F

自动释放池的前世今生 ---- 深入解析 autoreleasepool

http://draveness.me/autoreleasepool.html 关注仓库,及时获得更新:iOS-Source-Code-Analyze Follow: Draveness · Github 由于 Objective-C 中的内存管理是一个比较大的话题,所以会分为两篇文章来对内存管理中的一些机制进行剖析,一部分分析自动释放池以及 autorelease 方法,另一部分分析 retain.release 方法的实现以及自动引用计数. 写在前面 这篇文章会在源代码层面介绍 Objec

手动内存管理和自动释放池

手动内存管理 在进行内存管理的时候要注意内存管理的准则:谁开辟内存,谁释放内存(谁污染的谁治理) .开辟内存之后,对象的引用计数为1,只有继承自NSObject的对象才有内促管理的概念, 当对象引用计数为0的时候对象的内存会被清理. 下列关键字会开辟内存,对象引用计数器+1 alloc new copy mutableCopy 下列是内存管理的相关方法. retain :保留对象,对象的引用计数器+1. release : 释放对象,对象引用计数器-1. retainCount : 获取对象当前

objective-C 的内存管理之-自动释放池(autorelease pool)

如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣.但是有些时候,想知道某个对象在什么时候不再使用并不那么容易.如果下面的代码,看上去非常简单: Sample.h类接口部分 #import @interface Sample : NSObject { } -(NSString*) toString; @end Sample.m 类实现部分 #import "Sample.h"

黑马程序员----内存管理之四——《autorelease自动释放池》

内存管理之四——autorelease自动释放池 1.autorelease的基本使用 此对象方法会将对象放到一个自动释放池内: 当自动释放池被销毁时,就会对池子内的所有对象做一次release操作: 此方法会返回对象本身: 调用完此方法后,对象计数器的值不变,只有到自动释放池被销毁时才会对对象做一次release操作: 2.autorelease的好处 不用在关心对象被销毁的时间: 不用关心什么时候调用release操作: 3.autorelease的使用注意 占用内存较大的对象不要随便使用a

OC_内存管理(二)对象复制、循环引用问题、自动释放池

循环调用: 1.循环引用的问题 两个对象A.B,有可能会出现特殊情况:A中包含B的实例变量:B中也包含A的实例变量,如果这两个实例变量都是强引用(A有着B的实例变量所有权,B也有A的实例变量所有权),然后在两个对象销毁时,会出现A.B都不能正常销毁的情况.下面用代码来演示循环调用问题: ClassA的头文件Class.h代码 #import <Foundation/Foundation.h> //类的前向声明 @class ClassB; //类的前向声明与包含头文件的区别?Q: @inter

Objective -C Memory Management 内存管理 第一部分

Objective -C Memory Management??内存管理??第一部分 Memory management is part of a more general problem in programming called resource management. 内存管理是资源管理的一部分. Every computer system has finite resources for your program to use. These include memory, open fi