内存管理
来源:互联网 发布:剑网三萝莉脸型数据图 编辑:程序博客网 时间:2024/04/26 14:14
——————————————————————————————
1-对象所有权:
某个变量对指定的对象有使用权
2-引用计数
用来标识一个对象有几个使用者
3-引用计数器
记录使用者的个数的变量
变量类型 unsigned long
方法 retainCount
打印引用计数器的值 %lu
4-引用计数器的作用
作为对象是否要回收的依据
如果为0 要回收
如果>0 不要回收
5-对引用计数器的操作
向对象 发送 retain 消息 [obj retain];
使得对象的引用计数器+1
向对象 发送 release 消息
使得对象的引用计数器-1
6-对象回收注意:
一个对象如果回收的时候,系统自动的调用这个对象的 dealloc方法
MRC - 手动内存管理
ARC - 自动引用计数管理 (默认的)
——————————————————————————————
//创建一个实例对象
Person *p = [Personnew];
//Person *p = [[Person alloc]init];
//对象引用计数器的值?
//[p retainCount]; 可以获得对象的引用计数器的值
//对象创建完成后,默认的有一个所有者,就是他自己
NSUInteger n = [p retainCount];
[pretain]; // 让引用计数期的值+1
NSLog(@"n = %lu",n); // 1
//release 可以让对象的引用计数器的值 -1
//如果对象的引用计数器的值为 0
//那么此时这个对象会被立即回收
//会调用对象的 dealloc方法(系统自动调用)
[prelease]; //0
//
//NSLog(@"p.retainCount = %lu",[p retainCount]); //
[prelease];
———————————内存管理的原则———————————————————
只要对象的引用计数不为0 ,这个对象就不能释放
使用某个对象之前,先retain
使用之后 然后 relase
口诀:
1)谁创建,谁释放
Person *p = [Person new];
Person *p1 = p;
[p release]; //谁创建谁release
2)谁retain 谁 release
Person *p = [Person new];
Person *p1 = p;
[p1 retain]; //谁retain 谁release
[p1 release];
[p release]; //谁创建谁release
野指针: 1)指针变量没有赋值 2)指向的空间已经不可用了
空指针: 谁都不指向
内存泄露:
申请的空间,没有及时的释放
——————————————————————————————
内存泄露: 申请了空间,到程序结束,你都没有任何释放空间的操作
单个对象的内存泄露问题
1) 创建了对象以后,没有释放
2) retain和release的个数不匹配问题
3) 对象使用的过程中赋值了nil
4) 在对象方法中不当的使用 retain
——————————————————————————————
set方法的内存管理问题:
1)对于基本数据类型的实例变量
int _age,float _height;
-(void)setAge:(int)age{
_age = age;
}
2) 对于对象类型的set方法,应该按照如下去写
Car *_car;
-(void)setCar:(Car *)car{
if(_car!=car){
[_car release];
_car = [car retain];
}
}
-(void)dealloc{
[_car release];
[super dealloc];
}
*/
——————————————————————————@perperty 参数————
1) 什么时候使用 assign?
基本数据类型的时候 int float double char
BOOL struct enum
2) 什么时候使用retain
如果实例变量是 OC对象类型的时候,要使用 retain
如果使用了retain
注意: 在 dealloc 方法,中要 release一次
——————————————————————————————
/*
assign 直接赋值
set方法没有使用retain
-(void)setDog:(Dog *)dog{
_dog = dog;
}
retain release旧的值,retain新的值
-(void)setDog:(Dog *)dog{
if(_dog != dog){
[ _dog release];
_dog = [dog retain];
}
}
——————————————————————————————
@property 参数分为三组
1) 原子性
atomic(默认) - 线程安全
nonatomic - 线程不安全(如果程序中没有使用多线程,建议使用这个)
2) 读写控制
readwrite(默认) - 生成get和set方法
readonly - 生成get方法
3) set内存管理
assign(默认) retain copy
——————————————————————————————
typedef struct T{
int hour;
int min;
int sec;
}Time;
//定义日期的结构体
typedef struct D{
//定义年月日
int year;
int month;
int day;
//定义时间
Time t;
}MyDate;
——————————————————————————————
@class 使用注意:
@class 用在.h文件中
用来告诉编译器这是一个类,这个类有哪些属性和行为,不会去立即检查
.m中如果使用 @class引入的这个类的属性和方法,都需要重新导入一次
这个类的头文件
——————————————————————————————
循环引用 一弱一强 assign retain
——————————————————————————————
高
栈: 局部变量
堆: 动态申请的空间 对象
BSS: 没有初始化的全局变量和静态变量
数据区:已经初始化的全局变量和静态变量,字符串常量
代码区:程序编译后的代码的数据
低
//0x7fff5fbff7fc
int a = 10; // 局部变量
//0x100000f82
char *s = "abc";//字符串,数据区
NSLog(@"a addr = %p",&a); //高地址
NSLog(@"s addr = %p",s); //低地址
//0x100001070
NSString *str1 = @"abc"; //@"abc" 字符串常量 ,在常量区
NSString *str2 = [NSStringstringWithString:@"def"];
NSString *str3 = [[NSStringalloc] initWithString:@"abc"];
//0x100602420
//堆区
NSString *str4 = [NSStringstringWithFormat:@"aaa"];
NSString *str5 = [NSStringstringWithFormat:@"aaa"];
NSString *str6 = [[NSStringalloc] initWithFormat:@"bbbb"];
NSString *str7 = [[NSStringalloc] init];
[str7release];
//此时因为str1是一个常量,默认的引用计数是一个比较大的整数
NSLog(@"str1 addr = %p,str1.rc = %lu",str1,str1.retainCount); //小
NSLog(@"str2 addr = %p,str2.rc = %lu",str2,str2.retainCount); //小
NSLog(@"str3 addr = %p,str3.rc = %lu",str3,str3.retainCount); //小
NSLog(@"str4 addr = %p,str4.rc = %lu",str4,str4.retainCount); //小
NSLog(@"str5 addr = %p,str5.rc = %lu",str5,str5.retainCount); //小
NSLog(@"str6 addr = %p,str6.rc = %lu",str6,str6.retainCount); //小
NSLog(@"str7 addr = %p,str7.rc = %lu",str7,str7.retainCount); //小
}
return 0;
自动释放池
——————————————————————————————
/*
自动释放池的作用:
自动释放池结束的时候,会向自动释放池中所有的对象,发送一条 release
自动释放池的使用步骤:
1) 创建自动释放池
2) 把对象加入到自动释放中
怎么加入呢?
对象调用 autorelease方法,就把该对象加入到栈顶的自动释放中了
*/
#import <Foundation/Foundation.h>
#import "Car.h"
int main(int argc,const char *argv[]) {
@autoreleasepool {
Car *bigBen = [Carnew];
[bigBenrun];
[bigBen autorelease];//把对象 bigBen 加入到自动释放池中
// [bigBen release];
} // [bigBen release];
return 0;
———————————沙盒———————————————————
NSString *homePath =NSHomeDirectory(); //NSHomeDirectory 沙盒的根目录
NSLog(@"homePath = %@",homePath); // "/"
NSString *tempPath = NSTemporaryDirectory();
NSLog(@"tempPath = %@",tempPath);
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES);
NSString *path = [paths lastObject];
///Users/apple/Library/Developer/CoreSimulator/Devices/0B364173-7C28-4376-84F4-671126E16FAD/data/Containers/Data/Application/41568158-8808-49C5-A41D-6432A1F74D3B/Library/aaa/1.txt
//stringByAppendingPathComponent 给我们增加子路径
path = [path stringByAppendingPathComponent:@"aaa/1.txt"];
//Library 下创建一个文件夹 ,文件夹名是aaa/1.txt
NSLog(@"path = %@",path);
// NSFileManager *fm = [NSFileManager defaultManager];
// //在沙盒下Library中先创建目录
// [fm createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
NSString *str = @"abc";
BOOL isYes = [strwriteToFile:path atomically:YESencoding:NSUTF8StringEncodingerror:nil];
NSLog(@"%d",isYes);
——————————————————————————————
——————————————————————————————
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- 内存管理
- leetcode-20-Valid Parentheses
- Android之——AIDL小结
- hiho1192 简单的树嵌入(构造题)
- hdu 1533 Going Home (最小费用最大流)
- 杨辉三角_java_HDU2032
- 内存管理
- SSL/TLS双向认证实现(JAVA、TOMCAT)
- Fine-Grained Histopathological Image Analysis via Robust Segmentation and Large-Scale Retrieval文章总结
- 分离各位数
- 找数达人
- UIImage类目-返回一张拉伸的图片、自动设配6 7
- Linux内核驱动之自动创建设备文件
- 第五课 一致变量
- 英语学习--chap16 从属从句简化通则