引用计数:用来记录一块空间被指针指向的次数.
alloc:开辟一块空间,对象的引用计数由0到1,即 0 - 1;
release:对象的引用计数- 1;
copy:对象的引用计数+ 1;
retain:对象的引用计数+ 1;
dealloc:对引用计数为0的对象的空间回收;
内存管理容易出现的问题:
(1).内存泄漏:开辟的空间不回收,占用内存堆积,系统内存不够用,系统立即crash;
(2).野指针异常:指针指向不该指向的空间,一般是指针指向了一块已经被系统回收的空间;一般野指针问题,系统不会立即crash,而是在以后的指针指向之前已经释放的空间时,系统crash;
(3).过度释放:对于引用计数为0的对象,继续release操作释放空间,系统立即crash;
@autoreleasepool:对象的引用计数- 1,但是不会立即- 1,在@autoreleasepool内部开辟的空间,对象进行autorelease时,在@autoreleasepool结束时,里面的所有调用autorelease的对象引用计数- 1, @autoreleasepool称作自动释放池 对象在自动释放池内部开辟空间,称为将调用autorelease的对象放入自动释放池中,在@autoreleasepool结束时,称为将自动释放池销毁,自动释放池销毁时,会将释放池内的所有调用autorelease的对象引用计数- 1;
内存管理的基本原则:如果你对任何一个对象进行alloc,retain,copy之后,你就拥有了该对象的所有权,你就必须对它进行release或者autorelease.
@autoreleasepool {
for (int i = 0;i < 1000000000; i ++) {
// @autoreleasepool {
NSString *str = [[NSString alloc] init];
[str autorelease];
// }
}
}
//问题:在for循环内部开辟的空间,一直没有释放,造成内存内漏
//解决方法:(1).在内部的循环体外面加上一个自动释放池
//(2).将[str autorelease] 改为 [str release]
@autoreleasepool {
NSString *str = [[NSString alloc] init];
[str retain];
[str retain];
str = @"aa";
[str release];
[str release];
[str release];
}
//问题:(1).内存泄漏 :当 str = @"aa"时,指针重指向.本来指向堆区的指针变量指向了常量区,但是堆区开辟的空间没有释放
// (2).常量区内容系统管理:常量区的内容是系统管理的,并且常量区的引用计数,系统默认的是无穷大