大纲
一、验证内存是否泄漏
项目:EasyLife
自己创建的类,也要使用dealloc
在dealloc中使用NSLog(@"%s",func)验证内存是否泄漏
二、数组
项目:MemoryManage_Array0331
+号方法和字面量 创建 数组/字典
局部变量可用,全局变量不可用,易自动释放。
三、字典
项目:MemoryManage_Dictionary0331
字典中的allKeys方法:有返回值,会autorelease,声明为全局变量不安全。
若要用全局变量,就要自己retain
四、copy
项目:MemoryManage_Copy0331
1.何时使用copy和mutableCopy
①copy:实现了NSCopying协议的类才能使用
②mutableCopy:实现了NSMutableCopying协议的类才能使用
1.1 NSString
@interface NSString : NSObject
1.2 NSNumber
@interface NSNumber : NSValue
@interface NSValue : NSObject
2.返回值
2.1 copy return不可变对象
2.2 mutableCopy return可变对象
3.深浅拷贝
深拷贝:对象拷贝。新对象,值相同,内存地址不同。
浅拷贝:指针拷贝。新指针,指向原来的对象。
3.1 不可变对象
copy:浅拷贝
mutableCopy:深拷贝
3.2 可变对象
copy和mutableCopy:深拷贝
4.自定义类,深、浅拷贝取决于,对协议方法的实现
5.NSArray
NSArray *arr = [[NSArray alloc]initWithObjects:@"1",@"2", nil];
//浅拷贝
NSArray *arr1 = [arr copy];
//深拷贝,但arr内的对象(@"1",@"2")只是浅拷贝
NSArray *arr2 = [arr mutableCopy];
6.声明NSString类型的属性时,为什么要用copy
6.1 使用retain
用NSMutableString对象 赋值给 属性时,只是retainCount+1(两个指针指向同一个对象)
属性的值会随NSMutableString对象值的 改变而改变。
6.2 使用copy
NSMutableString对象 赋值给 属性时,是深拷贝(新的对象,内存地址不同,值和原来的对象一样)
NSMutableString对象 属性的值 相互独立
正文
一、验证内存是否泄漏
项目:EasyLife
自己创建的类中也要使用dealloc
在dealloc中使用NSLog(@"%s",func);验证内存是否泄漏
二、数组
项目:MemoryManage_Array0331
+号方法和字面量 创建 数组/字典
局部变量可用,全局变量不可用,容易自动释放。
源码:
//+号方法和字面量 创建数组/字典
//1.+号方法
//局部变量可用,全局变量不可用,容易自动释放。
NSArray *arr = [NSArray arrayWithObjects:@"1", nil];
NSLog(@"----%d",arr.retainCount);
//2.字面量方法
//会自动释放
NSArray *arr2 = @[@"1",@"2"];
NSDictionary *dict1 = @{@"1":@"键1",@"2":@"键2"};
//2.1 以下数组可使用字面量方法:heNanArr,shanDongArr,shanXiArr,anHuiArr
//因为_totalArr是alloc出来的,使用中,不用担心被自动释放
NSArray *heNanArr = [[NSArray alloc]initWithObjects:@"郑州",@"平顶山",@"南阳", nil];
NSArray *shanDongArr = [[NSArray alloc]initWithObjects:@"济南",@"日照",@"菏泽",@"烟台", nil];
_totalArr = [[NSArray alloc]initWithObjects:heNanArr,shanDongArr, nil];
//2.2 字面量方法相当于以下“+”号方法,
//容易autorelease
+ (NSArray *)createArray
{
NSArray *array = [[NSArray alloc]init];
[array autorelease];
return array;
}
三、字典
项目:MemoryManage_Dictionary0331
字典中的allKeys方法:有返回值,会autorelease,声明为全局变量不安全。
若要用全局变量,就要自己retain
文件:ViewController.m
NSArray *keyArr = [_provinceDic allKeys];*******************************声明为全局变量
allKeys方法:有返回值,所以它会autorelease,不能声明为全局变量******************
keyArr = [_provinceDic allKeys];
若要用全局变量,就要自己retain
[keyArr retain];
四、copy
项目:MemoryManage_Copy0331
1.何时使用copy和mutableCopy
①copy:实现了NSCopying协议的类才能使用
②mutableCopy:实现了NSMutableCopying协议的类才能使用
1.1 NSString
@interface NSString : NSObject
1.2 NSNumber
@interface NSNumber : NSValue
@interface NSValue : NSObject
2.返回值
2.1 copy,返回不可变对象
2.2 mutableCopy返回可变对象
3.深浅拷贝
深拷贝:对象拷贝。新对象,值相同,内存地址不同。
浅拷贝:指针拷贝。新指针,指向原来的对象。
3.1 不可变对象
copy:浅拷贝
mutableCopy:深拷贝
3.2 可变对象
copy和mutableCopy:都是深拷贝
4.对于自定义类来说,深拷贝和浅拷贝取决于,对协议方法的实现
5.NSArray
NSArray *arr = [[NSArray alloc]initWithObjects:@"1",@"2", nil];
//浅拷贝
NSArray *arr1 = [arr copy];
//深拷贝,但arr内的对象(@"1",@"2")只是浅拷贝
NSArray *arr2 = [arr mutableCopy];
6.声明属性,NSString为什么要用copy
6.1 使用retain
NSMutableString对象赋值给NSString属性时,只是retainCount+1(两个指针指向同一个对象)
NSString属性的值会随NSMutableString对象值的改变而改变。
6.2 使用copy
NSMutableString对象赋值给NSString属性时,是深拷贝(新的对象,值和原来的对象一样)
NSMutableString对象 NSString属性 的值 相互独立
源码:
文件:People.m
- (id)copyWithZone:(NSZone *)zone
{
People *people = [[People alloc]init];
return people;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return self;
}
文件:ViewController.m
@interface ViewController ()
@property (nonatomic,retain)NSString *string;
@property (nonatomic,copy)NSString *string1;
@end
@implementation ViewController
- (void)dealloc
{
[_string release];
[_string1 release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
//1.何时使用copy和mutableCopy
//①copy:实现了NSSCoping协议的类才能使用
//②mutableCopy:实现了NSMutableCoping协议的类才能使用
//NSString
// @interface NSString : NSObject
NSString *text = @"aaa";
[text copy];
[text mutableCopy];
//2.返回值
NSString *text = @"aaa";
//2.1 使用copy 返回 不可变对象
NSMutableString *text1 = [text copy];
//2.2 使用mutableCopy 返回可变对象
NSMutableString *text2 = [text mutableCopy];
//3.深浅拷贝
//深拷贝:对象拷贝。新对象,值相同,内存地址不同。
//浅拷贝:指针拷贝。新指针,指向原来的对象。
//3.1 不可变对象
//copy:浅拷贝
//mutableCopy:深拷贝
NSLog(@"%p------%p------%p",text,text1,text2);//内存地址:text == text1 != text2
//3.2 可变对象
//copy和mutableCopy:都是深拷贝
NSLog(@"%p======%p======%p",mText,mText1,mText2);//内存地址:均不相等
//4.对于自定义类来说,深拷贝和浅拷贝取决于,对协议方法的实现
//在People中,我们将协议方法分别实现如下改变
//copy:深。 mutableCopy:浅。
People *p1 = [[People alloc]init];
People *p2 = [p1 copy];//深拷贝
People *p3 = [p1 mutableCopy];//浅拷贝
NSLog(@"%p======%p======%p",p1,p2,p3);//内存地址:p1 == p3 != p2
//5.NSArray
NSArray *arr = [[NSArray alloc]initWithObjects:@"1",@"2", nil];
//浅拷贝
NSArray *arr1 = [arr copy];
//深拷贝,但arr内的对象(@"1",@"2")只是浅拷贝
NSArray *arr2 = [arr mutableCopy];
//6.声明属性,NSString为什么要用copy
//对象有一个特性:子类对象可以赋给父类的指针。
NSMutableString *mString = [[NSMutableString alloc]initWithString:@"mmm"];
//使用retain
//NSMutableString对象赋值给NSString属性时,只是retainCount+1(两个指针指向同一个对象)
//NSString属性的值会随NSMutableString对象值的改变而改变。
self.string = mString;
//使用copy
//NSMutableString对象赋值给NSString属性时,是深拷贝(新的对象,值和原来的对象一样)
//NSMutableString对象 NSString属性 的值 相互独立
self.string1 = mString;
[mString appendString:@"111"];
NSLog(@"mString = %@,_string = %@",mString,self.string);
}
//retain
- (void)setString:(NSString *)string
{
if (_string != string)
{
[_string release];
_string = [string retain];//仅仅是retainCount+1
}
}
//copy
- (void)setString1:(NSString *)string1
{
if (_string1 != string1)
{
[_string1 release];
_string1 = [string1 copy];//可变对象调用copy,是深拷贝
}
}
@end