iOS-OC内存管理

目标

1.【理解】内存管理

2.【掌握】第一个MRC程序

3.【掌握】内存管理的原则

4.【理解】野指针与僵尸对象

5.【理解】单个对象的内存管理

6.【理解】多个对象的内存管理

7.【掌握】set方法的内存管理

8.【掌握】@property参数

9.【掌握】@class关键字

10.【理解】循环retain

一、内存管理

程序在运行过程中会在堆空间创建大量的对象,当对象不再使用的时候,系统并不会自动释放堆空间中的对象(基本数据类型是由系统自动管理的)。如果一个对象创建并使用后没有得到及时释放,那么这对象会直到程序结束才会被释放,这样就会占用大量内存空间。其他高级语言如C#、Java都是通过垃圾回收机制(GC)来解决这个问题的,但在OC中并没有类似的垃圾回收机制,因此它的内存管理就需要由程序员手动维护。并且栈空间、BSS段、数据段、代码段中的数据都是由系统自动管理的,所以这些区域的数据不需要由程序员来管理,我们只需要管理堆空间中的数据,也就是OC对象的释放需要我们来管理。

引用计数器

OC中内存的管理是依赖对象引用计数器来进行的,在OC中每个对象内部都有一个与之对应的整数(retainCount),叫“引用计数器”。当一个对象在创建之后它的引用计数器默认值为1,如果一个对象的引用计数器为0,则系统会自动调用这个对象的dealloc方法来销毁这个对象。

内存泄露

一个对象在使用完没有回收,直到程序结束的时候才被回收,这种现象就叫做内存泄露。

如何操作对象的引用计数器?

调用对象的retain方法,对象的引用计数器就会+1。

调用对象的release方法,对象的引用计数器就会-1。

调用对象的retainCount方法,就会得到这个对象的引用计数器的值。

总结:

当我们要使用一个对象的时候,应该为这个对象发送一条retain消息。当我们不再使用一个对象的时候,就应该为这个对象发送一条release消息。当对象的引用计数器为0的时候,系统就会调用这个对象的dealloc方法来销毁这个对象,所以我们一般会重写dealloc方法来监控对象的销毁。

二、第一个MRC程序

OC内存管理的分为MRC(Manual Reference Counting)手动引用计数ARC(Automatic Reference Counting)自动引用计数。见名知意,MRC是程序员自己手动记录对象的引用计数,而ARC则是系统自动记录对象的引用计数。由于ARC机制是在Xcode4.2后推出的,所以默认情况下Xcode是自动开启ARC机制的,我们要使用MRC就必须关闭ARC。

为了便于监控对象释放,我们经常需要重写dealloc方法。并且重写dealloc方法需要遵循一些规范,在子类的dealloc方法最后必须调用父类的dealloc方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

//Person.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

//Person.m文件

#import "Person.h"

@implementation Person

//重写dealloc方法

- (void)dealloc {

NSLog(@"人挂了...");

//在子类dealloc方法最后必须调用父类dealloc方法

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

//使用alloc创建对象,默认对象引用计数器的值为 1

Person *p = [[Person alloc] init];

//给对象发送release消息只是让引用计数器 -1,并不是一定会让对象引用计数器变为0

[p release];

//调用对象的dealloc方法,输出

//人挂了...

return 0;

}

三、内存管理的原则

只在有人使用这个对象的时候才为对象发送retain消息,只在一个人不再使用对象的时候才为对象发送release消息。遵守谁创建谁release,谁retain谁release的原则。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

//Person.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

//Person.m文件

#import "Person.h"

@implementation Person

//重写dealloc方法

- (void)dealloc {

NSLog(@"人挂了...");

//在子类dealloc方法最后必须调用父类dealloc方法

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

//使用alloc创建对象,引用计数器 +1

Person *p = [[Person alloc] init];

//给对象发送一条retain消息,引用计数器 +1

[p retain];

//给p对象发送一条retainCount消息,返回引用计数器的值

NSUInteger count = [p retainCount];

NSLog(@"count = %lu",count);

//给对象发送release消息只是让引用计数器 -1,并不是一定会让对象引用计数器变为0

[p release];

//再发送一条release,此时引用计数器就为0了

[p release];

//调用对象的dealloc方法,输出

//人挂了...了...

return 0;

}

注意:

1.为对象发送release消息不是让对象释放,而是让对象的引用计数器-1。

2.当对象引用计数器的值为0时,系统会立即调用对象的dealloc方法释放对象。

3.创建谁release,谁retain谁release。

四、野指针与僵尸对象

C语言中的野指针:一个指针变量指向一块随机的内存空间,也就是未初始化的指针变量,这个指针就叫做野指针。

OC语言中的野指针:指针指向的对象已经被释放了,这个指针就叫做野指针。

僵尸对象:已经被释放的对象,叫做僵尸对象,也就是通过野指针访问的对象就是僵尸对象。注意一旦一个指针成为了野指针,就不要通过野指针去访问对象的成员了。

每次通过一个指针去访问一个对象的时候,都会去检查这个对象是否是僵尸对象,如果是就报错。默认情况下Xcode是不会自动检测僵尸对象,那么如何开启Xcode对僵尸对象的自动检测?

当一个对象被回收后,就为指向这个对象的指针赋值nil,可避免访问僵尸对象。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

//Person.h文件

#import <Foundation/Foundation.h>

@interface Person : NSObject

- (void)eat;

@end

//Person.m文件

#import "Person.h"

@implementation Person

- (void)eat {

NSLog(@"人吃饭");

}

//重写dealloc方法

- (void)dealloc {

NSLog(@"人挂了...");

//调用父类dealloc方法

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

Person *p = [[Person alloc] init];

//release让引用计数器 -1,此时对象引用计数器为0.对象被销毁

[p release];

//p指针赋值nil

p = nil;

//给p对象发送消息不会报错,只会啥都不发生

[p eat];

return 0;

}

五、单个对象的内存管理

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

Person *p = [[Person alloc] init];//retainCount == 1

[p retain];//retainCount == 2

[p retain];//retainCount == 3

//    //只有retain没有release

[p release];//retainCount == 2

[p release];//retainCount == 1

//    //在不适当的时候为指针赋值nil

//    p = nil;//对象还没释放,就将指针赋值nil

[p release];//retainCount == 0

return 0;

}

六、多个对象的内存管理

当一个对象的属性是另一个对象的时候,在这个属性的setter方法中,将传入的对象先retain一次,再赋值给属性。并在dealloc方法中对属性进行一次release。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

//Car.h文件

#import <Foundation/Foundation.h>

@interface Car : NSObject

- (void)run;

@end

//Car.m文件

#import "Car.h"

@implementation Car

-(void)run {

NSLog(@"车启动");

}

- (void)dealloc {

NSLog(@"车挂了...");

//调用父类dealloc方法

[super dealloc];

}

@end

//Person.h文件

#import <Foundation/Foundation.h>

#import "Car.h"

@interface Person : NSObject

@property Car *car;

- (void)drive;

@end

//Person.m文件

#import "Person.h"

@implementation Person

- (void)setCar:(Car *)car {

//retain传入的对象,因为多了一个指针(_car属性)指向这个传入的对象

//retain返回值是对象本身

_car = [car retain];

}

- (void)drive {

NSLog(@"车启动");

//调用_car的run方法

[self.car run];

}

- (void)dealloc {

NSLog(@"人挂了...");

//在人挂的时候让车也挂

[self.car release];

//调用父类dealloc方法

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

//实例化人和车对象

Person *p = [[Person alloc] init];

Car *bmw = [[Car alloc] init];

//给人一辆车

p.car = bmw;

//后创建的对象先release

[bmw release];

bmw = nil;

[p release];

p = nil;

return 0;

}

七、set方法的内存管理

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

//Car.h文件

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property int speed;

- (void)run;

@end

//Car.m文件

#import "Car.h"

@implementation Car

-(void)run {

NSLog(@"车启动");

}

- (void)dealloc {

NSLog(@"时速为%d车挂了...",_speed);

[super dealloc];

}

@end

//Person.h文件

#import <Foundation/Foundation.h>

#import "Car.h"

@interface Person : NSObject

@property Car *car;

@property NSString *name;

- (void)drive;

@end

//Person.m文件

#import "Person.h"

@implementation Person

- (void)setCar:(Car *)car {

//判断传入对象是否和属性的旧值是同一对象

if (_car != car) {

//不是同一对象就release旧值

[_car release];

//retain新值

_car = [car retain];

}

}

- (void)drive {

//调用_car的run方法

[_car run];

}

- (void)dealloc {

NSLog(@"%@挂了...",_name);

//对象释放前将属性指向的对象release一次,表示不指向那个对象了

[_car release];

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

//实例化两个人对象

Person *p1 = [[Person alloc] init];//p1的retainCount == 1

Person *p2 = [[Person alloc] init];//p2的retainCount == 1

//分别为两个人对象的_name赋值

p1.name = @"jack";

p2.name = @"rose";

//实例化两个车对象

Car *bmw = [[Car alloc] init];//bmw的retainCount == 1

Car *benz = [[Car alloc] init];//benz的retainCount == 1

//分别为两个车对象的_speed赋值

bmw.speed = 100;

benz.speed = 80;

//p1指向bmw

p1.car = bmw;//bmw的retainCount == 2

//p2也指向bmw

p2.car = bmw;//bmw的retainCount == 3

//p2不指向bmw了,指向benz

p2.car = benz;//bmw的retainCount == 2 , benz的retainCount == 2

[benz release];//benz的retainCount == 1

[p2 release];//p2的retainCount == 0 调用了p2的delloc方法,再调用benz的release. benz的retainCount == 0  所以rose挂了,benz也挂了

[bmw release];//bmw的retainCount == 1

[p1 release];//p1的retainCount == 0 调用了p1的delloc方法,再调用bmw的release. bmw的retainCount == 0  所以jack挂了,bmw也挂了

/* 输出

rose挂了...

时速为80车挂了...

jack挂了...

时速为100车挂了...

*/

return 0;

}

八、@property参数

@property的参数分为三类,中间用逗号分隔,每类参数可以从上图三类参数中任选一个。如果不进行设置或者只设置其中一类参数,程序会使用三类中的各类的默认参数,默认参数:(atomic,readwrite,assign)。

格式:@property ([参数1,参数2,参数3]) 数据类型 名称;    // []里表示可选

一般情况下如果在多线程开发中一个属性可能会被两个及两个以上的线程同时访问,此时可以考虑atomic属性,否则建议使用nonatomic,不加锁,效率较高。readwirte方法会生成getter、setter两个方法,如果使用readonly则只生成getter方法。关于setter方法处理需要特别说明,假设我们定义一个属性a,这里列出三种方式的生成代码:

assign,用于基本数据类型

1

2

3

- (void)setA:(int)a {

_a = a;

}

retain,通常用于非字符串对象

1

2

3

4

5

6

- (void)setA:(Car *)a {

if(_a != a){

[_a release];

_a = [a retain];

}

}

copy,通常用于字符串对象

1

2

3

4

5

6

- (void)setA:(NSString *)a{

if(_a != a){

[_a release];

_a = [a copy];

}

}

我们可以在参数中指定@property生成的setter、getter的方法名称,一般情况下,当属性的类型是一个BOOL类型的时候,我们可以指定getter方法名以is开头,这样增强代码可阅读性。

1

2

3

4

5

6

7

8

9

10

11

12

13

@property (nonatomic,assign,readwrite,getter=isRich) int rich;

//生成的setter、getter方法声明

- (void)setRich:(BOOL)rich;

- (BOOL)isRich;

//生成的setter、getter方法实现

- (void)setRich:(BOOL)rich {

}

- (BOOL)isRich {

}

实际应用案例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

//Book.h文件

#import <Foundation/Foundation.h>

@interface Book : NSObject

@property (nonatomic, copy) NSString *bookName;

@end

//Book.m文件

#import "Book.h"

@implementation Book

- (void)dealloc {

NSLog(@"<<%@>>被烧了",_bookName);

[_bookName release];

[super dealloc];

}

@end

//Student.h文件

#import <Foundation/Foundation.h>

#import "Book.h"

@interface Student : NSObject

@property (nonatomic, retain) Book *book;

@end

//Student.m文件

#import "Student.h"

@implementation Student

- (void)dealloc {

NSLog(@"<<%@>>",_book.bookName);

[_book release];

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Student.h"

int main(int argc, const char * argv[]) {

Student *stu = [[Student alloc] init];//stu的retainCount == 1

Book *book = [[Book alloc] init];//book的retainCount == 1

stu.book = book;//book的retainCount == 2

stu.book.bookName = @"风流少女";

[book release];//book的retainCount == 1

[stu release];//stu的retainCount == 0,调用stu的dealloc方法,再调用book的release,则book的retainCount == 0

/*

输出

学生挂了

<<风流少女>>被烧了

*/

return 0;

}

九、@class关键字

当两个类相互包含的时候,就会造成死循环。在.h文件中不能包含和自己关联的那个类的头文件,因为一旦包含就会造成死循环。应该使用@class来声明一个类存在,如果在.m文件中需要使用用@class声明的类的成员时,就在.m文件中包含即可。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

//Book.h文件

#import <Foundation/Foundation.h>

@class Student;//如果不需要使用类中的成员可以使用@class告诉编译器,Student是一个类

@interface Book : NSObject

@property (nonatomic, copy) NSString *bookName;

@property (nonatomic, assign) Student *owner;

- (void)showOwner;

@end

//Book.m文件

#import "Book.h"

#import "Student.h"

@implementation Book

- (void)showOwner {

//使用了Student类的成员_name,直接包含头文件即可

NSLog(@"%@的主人是%@",self.bookName,self.owner.name);

}

- (void)dealloc {

NSLog(@"书挂");

[_bookName release];

[super dealloc];

}

@end

//Student.h文件

#import <Foundation/Foundation.h>

@class Book;//如果不需要使用类中的成员可以使用@class告诉编译器,Book是一个类

@interface Student : NSObject

@property (nonatomic, copy) NSString *name;

@property (nonatomic, retain) Book *book;

- (void)showBook;

@end

//Student.m文件

#import "Student.h"

#import "Book.h"

@implementation Student

- (void)showBook {

//使用了Book类的成员_bookName,直接包含头文件即可

NSLog(@"%@的书名叫%@",self.name,self.Book.bookName);

}

- (void)dealloc {

NSLog(@"学生挂");

[_name release];

[_book release];

[super dealloc];

}

@end

十、循环retain

当两个类互相引用的时候,如果两个类的@property的参数都是retain就会出现循环引用造成内存泄露。解决办法是一个类使用retain,另一个类使用assign。使用assign的类不用在dealloc方法中对那个属性release。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

//Book.h文件

#import <Foundation/Foundation.h>

@class Student;//告诉Book,Student是一个类

@interface Book : NSObject

@property (nonatomic, copy) NSString *bookName;

@property (nonatomic, assign) Student *owner;//使用assign

@end

//Book.m文件

#import "Book.h"

@implementation Book

- (void)dealloc {

NSLog(@"<<%@>>释放",self.bookName);

[super dealloc];

}

@end

//Student.h文件

#import <Foundation/Foundation.h>

@class Book;//告诉Student,Book是一个类

@interface Student : NSObject

@property (nonatomic, copy) NSString *name;

@property (nonatomic, retain) Book *book;//使用retain

@end

//Student.m文件

#import "Student.h"

@implementation Student

- (void)dealloc {

NSLog(@"<<%@>>释放了",self.name);

[_book release];

[super dealloc];

}

@end

//main.m文件

#import <Foundation/Foundation.h>

#import "Book.h"

#import "Student.h"

int main(int argc, const char * argv[]) {

Book *book = [[Book alloc] init];//book的retainCount == 1

book.bookName = @"风流少女";

Student *student = [[Student alloc] init];//student的retainCount == 1

student.name = @"牛逼哥";

book.owner = student;//因为是assign,所以不会retain传入的student,则student的retainCount == 1

student.book = book;//因为是retain,会retain传入的book,则book的retainCount == 2

[student release];//student的retainCount == 0,会调用student的dealloc方法,再调用一次book的release。则book的retainCount == 1

student = nil;

[book release];//book的retainCount == 0

book = nil;

/* 输出

<<牛逼哥>>释放了

<<风流少女>>释放

*/

return 0;

}

时间: 2024-08-08 12:16:46

iOS-OC内存管理的相关文章

OC内存管理

OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效. 本质原因是因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象存储于堆中,当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也

【0 - 1】OC内存管理

一.内存管理概述 垃圾回收机制(GC):由系统管理内存,程序员不需要管理. OC中的垃圾回收:在OC2.0版加入垃圾回收. OC与iOS:OC有垃圾回收机制,但是iOS屏蔽了这个功能.原因:iOS运行在移动设备上,硬件资源有限(内存.电量,发热控制等方面),而垃圾回收机制有一定弊端(以java的垃圾回收机制为例,它的垃圾回收并不是当程序结束之后,立刻回收内存,而是当程序需要内存,而剩余内存不够当前申请内存的程序使用时,才进行内存的回收).即OC有垃圾回收机制,iOS平台屏蔽了OC垃圾回收的功能,

OC内存管理相关整理

OC内存管理 一.基本原理 (一)为什么要进行内存管理.内存管理的目的是什么? 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效 管理目的: 1.不要释放或者覆盖还在使用的内存,这会引起程序崩溃: 2.释放不再使用的内存,防止内存泄露.(ios程序的内存资源很是宝贵.) 本质原因是因

OC内存管理详解

前言 由于移动设备的内存有限,所以我们需要对内存进行严格的管理,以避免内存泄露造成资源浪费.在OC中,只有对象才属于内存管理范围,例如int.struce等基本数据类型不存在内存管理的概念.在iOS开发中,对内存的管理实际上就是对引用计数器的管理. OC内存管理的三种方式 自动垃圾收集(Automatic Garbage Collection): 手动引用计数器(Manual Reference Counting)和自动释放池: 自动引用计数器(Automatic Reference Count

OC 内存管理机制总结

OC 内存管理机制总结 一:OC内存管理机制目前分为两块,其一自动内存管理机制,其二手动内存管理机制: 1.首先我们从自动内存管理机制讲起: 1)什么是自动内存管理机制,自动内存管理机制就是程序中所创造的成员变量交由系统统一处理,不需要外部人员干预,有点像java中gc(垃圾回收机制). 2)之前是没有自动内存管理机制的,后期苹果想拓展自己的开发市场,吸引其他平台开发者入住ios开发阵营,其中收到内存管理是很发杂的一块,对于转入IOS开发者不利,因此苹果推出了自动内存管理机制. 2.接下来我们将

OC内存管理总结,清晰明了!

<span style="font-size:18px;">OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效. 本质原因是因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象

OC内存管理(转载)

OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等. 管理范围:任何继承NSObject的对象,对其他的基本数据类型无效. 本质原因是因为对象和其他数据类型在系统中的存储空间不一样,其它局部变量主要存放于栈中,而对象存储于堆中,当代码块结束时这个代码块中涉及的所有局部变量会被回收,指向对象的指针也

iOS之内存管理(ARC)

iOS的内存管理,相信大家都不陌生,之前是使用的MRC,由开发人员手动来管理内存,后来使用了ARC,来由系统管理内存.本文主要讲讲Autorelease,Core Foundation对象在内存管理方面要注意的地方. Autorelease 提到内存管理,就不得不提autorelease,虽然我们平时开发中很少会感知到它的存在.autorelease就是自动释放的意思,如果变量使用autorelease来修饰,就表明变量的释放由系统来完成. autoreleasepool是由runloop在开启

说说iOS与内存管理(上)

http://www.cocoachina.com/ios/20150625/12234.html 说起内存管理,看似老生常谈,而真正掌握内存管理的核心其实并不简单.ARC/MRR以及“谁分配谁就负责释放”这种基本原则是很重要的,但不是本文要讨论的重点.之前本人还没在小站发过相关的文章,本篇文章中,我本人是想结合实际开发和调试中遇到的一些细节问题,来谈谈iOS的内存管理内在机制和调试方法. 上一篇文章已经是4月份的了,时间飞快又过去了好久,小站5月份没有文章更新,罪过罪过.最近小站的站长我又转换

OC内存管理-1

栈区:从高到低分配 堆区:从低到高 BSS段:没有初始化的 数据区: 代码段: OC内存管理方式: 1 MRC 手动内存管理 2 ARC 自动内存管理 nil是给对象赋空值 下个有道云笔记 内存管理 一.总结: 1.只有OC对象才需要内存管理,基本数据类型无效 2.OC对象存放在堆里面 3.非OC对象一般放在栈里面(栈内存会被系统自动回收) 二.引用计数器: 1.每个OC对象都有自己的引用计数器 2.它是一个整数(int) 3.表示有多少人正在使用这个对象 4.每个OC对象都有4个字节的存储空间