糖糖的iOS专题我的测试收藏iOS开发

iOS 内存管理

2016-06-23  本文已影响124人  _凉风_

一、Manual Reference Counting「手动引用计数」手动内存管理

1. 内存管理的重要性

管理范围:任何继承了 NSObject 的对象「其他基本数据类型 struct、enum 无效」

2. 内存分配

按地址的由高到低排序为:
1)系统内核
2)栈区

3)空余区域
4)堆区

5)BSS段「程序启动后自动加载」:存储未初始化的全局变量
6)数据段「程序启动后自动加载」

7)代码段「程序启动后自动加载」

某些架构也允许代码段为可写,即允许修改程序
在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等
假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段

3. 引用计数器

定义:

作用:

方法:

4. 对象的销毁

当对象的引用计数器值为 0,对象被回收,调用 retain方法也是错误的

避免野指针错误:<code>[p release]; p = nil;</code>

僵尸对象:所占用内存已经被回收的对象
野指针:指向僵尸对象「不可用内存 EXC_BAD_ACCESS」的指针
空指针:没有指向任何东西的指针,存储的东西是 (nil、NULL、0)
给指针发送消息:空指针,不会报错;野指针,会报错

5. 遵循原则

6. @property - 中 参数

允许多个参数:@property (nonatomic, retain) Book * book;「但 多个参数值不能相同」

6.1 set方法内存管理

@property (copy) myBlock block;「此时把Block函数由栈转移到堆中,不会拷贝block函数,只是转移了」

@property (copy) Book * book; // 此时变为深复制,防止外界修改内部数据
- (void)setBook: (Book*)book {
    _book = [book copy];
}
- (void)setBook: (Book*)book {
    if(_book != book) {    // 1. 先判断是不是新传进来的对象
        [_book release];   // 2. 对旧对象 release
        _book = [book retain];  // 3. 对新对象 retain
    }
}
// 以下代码为人工必须添加的代码
- (void)dealloc {
    [_book release];
    [super release]; // 一定要有,一定放在最后
}

6.2 控制成员变量的 读写「是否要生成set、get方法」

6.3 多线程管理

6.4 setter 和 getter方法重命名

@property int max; 默认生成

{    
   int  _max;
}
- (void)setMax : (int)max;
- (int)max;
// ...

@property ( setter = imax: , getter = rmax) int max; 默认生成

{  
   int  _max; // 不影响成员变量名
}
- (void)imax : (int)max;
- (int)rmax;
// ...
p.imax = 100;
p.max = 100; 
@property (getter = isRich) BOOL rich;

7. - (id)autorelease 方法定义:

优点:

缺点:

注意:

格式:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Book *book = [[[Book alloc] init] autorelease];
[pool release]; // 在IOS中用 release,MAC中用 [pool drain]
// 自动释放池-1
@autoreleasepool{ 
    Book *book = [[[Book alloc] init] autorelease]; // 添加到自动释放池-1中
    // 这里用了 alloc,用 autorelease对应,不要在调用 release 
    // 自动释放池-2
    @autoreleasepool{ 
        Book *book2 = [[[Book alloc] init] autorelease]; // 添加到自动释放池-2中
    }
}
// 封装
+ (id)book{
    // 使用 self防止 Book子类调用此方法创建的是父类对象,而不是子类对象
    return [[[self alloc] init] autorelease];
}
// 调用

@autoreleasepool{ 
    Book *b = [Book book];
}

二、Automatic Reference Counting「自动引用计数」自动内存管理

1. ARC基础

指针:

判断准则:只要没有强指针对象,就会释放对象
特点:

2. @property - 参数 下

在编译器 ARC模式下

3. 循环引用

#import <Foundation/Foundation.h>
@class B
@interface A : NSObject 
@property (nonatomic, retain) B *b; // 一端用 retain
@end

#import <Foundation/Foundation.h>
@class A
@interface B: NSObject 
@property (nonatomic, assign) A *a; // 一端用 assign
@end

#import <Foundation/Foundation.h>
#import "A.h"

#import "B.h"
int main(){
    A *a = [[A alloc] init];
    B *b = [[B alloc] init];
    a.b = b;
    b.a = a;
    [a release];
    [b release];
}
#import <Foundation/Foundation.h>
@class Dog;
@interface Person : NSObject
@property (nonatomic, strong) Dog *dog; // 一端用 strong
@end

#import <Foundation/Foundation.h>
@class Person;
@interface Dog : NSObject
@property (nonatomic, weak) Person *person; // 一端用weak
@end

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Dog.h"
int main(){
    Person *p = [[Person alloc] init];
    Dog *d = [[Dog alloc] init];
    p.dog = d;
    d.person = p;
}
上一篇下一篇

猜你喜欢

热点阅读