Objective-C:内存管理的小结
内存管理:
对于对象类型的实例变量,可以使用@property自动生成相应地存取方法,
但@property中必须要采用retain的内存设置;
assign用于基本的数据类型,不需要获取所有权的类型。
ARC:
strong 相当于MRC中的retain
assign 用于基本的数据类型
weak 不需要获取所有权的对象类型
unsafeunretain 用在不支持weak的旧版本中
对象复制中的浅复制和深复制:
浅复制:复制对象时,如果对象中包含对象类型的实例变量,只是复制指针。新对象中的对象类型实例变量和旧对象中的对象类型实例变量指的是同一个对象。任何一方实例变量对对象做修改,另一方实例变量指向的该对象也就改变了。
深复制:复制对象时,如果对象中包含对象类型的实例变量,要对对象类型的实例变量也要做对象复制。新对象中的对象类型实例变量和旧对象中的对象类型实例变量指的是不同的对象。不管任何一方实例变量对对象做修改,都互相不影响对方所指向的对象的内容。
用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。
8、自动释放池(管理需要延迟释放的对象)
由new、copy、alloc创建的对象不会自动入池,需要通过发送autorelease消息,将一个对象添加到其中,以便最后释放:[MyFranction autorelease]
1 #import <Foundation/Foundation.h> 2 #import "Book.h" 3 void ex1(); 4 void ex2(); 5 void ex3(); 6 void ex4(); 7 void ex5(); 8 int main(int argc, const char * argv[]) 9 { 10 //ex1(); 11 //ex2(); 12 //ex3(); 13 //ex4(); 14 ex5(); 15 return 0; 16 }
(1)创建自动释放池的两种方法:
-NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]
[pool release]《==等价于==》[pool drain];
1 void ex1() 2 { 3 //创建一个自动释放池对象 4 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 5 //自动释放池的使用 6 Book *book = [[Book alloc]initWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6]; 7 8 //将book对象加入自动释放池 9 [book autorelease]; 10 [book print]; 11 12 NSLog(@"autorelease last"); 13 //清空自动释放池--会给每个管理的对象发送release消息 14 [pool release];//===[pool drain] 15 }
或者
-@autoreleasePool
{
}
1 //创建自动释放池的第一种方式 2 void ex2() 3 { 4 @autoreleasepool { 5 6 //自动释放池的使用 7 Book *book = [[Book alloc]initWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6]; 8 9 //将book对象加入自动释放池 10 [book autorelease]; 11 [book print]; 12 13 NSLog(@"autorelease last"); 14 }//在自动释放池结束时,会给每个管理的对象发送release消息 15 }
(2)延迟释放对象
在OC的内置类(NSString、NSArray等)中提供的类方法创建的对象实例都是“延迟释放对象”,也就是在对象创建完成后将对象加入自动释放池。
1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price 2 { 3 return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease]; 4 }
1 void ex3() 2 { 3 @autoreleasepool { 4 //这种对象不需要我们去给它们发release消息。 5 Book *book = [Book bookWithTitle:@"OC" andAuthor:@"Jobs" andPrice:35.6]; 6 [book print]; 7 //[book release]; 8 } 9 }
(3)自动释放池的嵌套
对象在加入自动释放池时,加入的是离它最近的自动释放池,目的是为了让延迟释放的对象尽快得到释放,降低程序运行期间的内存占用;
在管理多个自动释放池时,采用了类似“栈”的结构,可以让对象轻松的找到离它最近的(栈顶的)自动释放池。
1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price 2 { 3 return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease]; 4 }
1 void ex4() 2 { 3 @autoreleasepool { 4 Book *book = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6]; 5 [book print]; 6 @autoreleasepool { 7 Book *book2 = [Book bookWithTitle:@"iOS" andAuthor:@"Bill" andPrice:55.6]; 8 [book2 print]; 9 } 10 } 11 }
(4)独立的自动释放池
当程序中出现创建大量延迟释放对象的代码时,最好给它一个独立的自动释放池,保证这些对象在不用了后马上释放掉
1 +(Book*)bookWithTitle:(NSString*)title andAuthor:(NSString*)author andPrice:(CGFloat)price 2 { 3 return [[[Book alloc]initWithTitle:title andAuthor:author andPrice:price]autorelease]; 4 }
1 void ex5() 2 { 3 @autoreleasepool { 4 for(int i=0; i<10000; i++) 5 { 6 @autoreleasepool {//独立的自动释放池 7 Book *book = [Book bookWithTitle:[NSMutableString stringWithFormat:@"book%d",i+1] andAuthor:[NSMutableString stringWithFormat:@"author%d",i+1 ] andPrice:20+i]; 8 [book print]; 9 } 10 } 11 } 12 }