---------------- ASP.Net+Unity开发、.Net培训、期待与您交流!----------------
《OC9-内存管理1-retain和release》学习总结
1、内存管理范围:任何集成了NSObject的对象,对基本数据类型无效。
2、每一个对象内部都保存了一个与之相关联的整数,称之为引用计数器。
3、当使用alloc、new或copy创建一个对象时,对象的引用计数器被设置为1。
4、给对象发送一条retain消息,可以使引用计数器值加1。
5、给对象发送一条release消息,可以使引用计数器值减1。
6、当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存会被系统回收,并且OC会自动向对象发送一条dealloc消息。
7、dealloc方法禁止直接调用,但一般会被重写。
8、retainCount方法可以获得当前对象的引用计数器值。
9、谁创建,谁释放,谁污染,谁治理,如果通过alloc、new或copy创建了一个对象,那么你必须调用release或autorelease。
10、除了alloc、new或copy之外的方法创建的对象默认都声明了autorelease。
11、谁retain,谁release,只要你调用了retain,那么你必须调用release。
12、dealloc示例。
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property int age;
@end
#import "Student.h"
@implementation Student
// 可省略.
@synthesize age = _age;
- (void)dealloc {
// 一定要在最后调用super的dealloc方法.
[super dealloc];
}
@end
13、retain和release示例。
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// 引用计数器值为1.
Student *stu = [[Student alloc] init];
// 引用计数器值加1,值为2.
[stu retain];
// 引用计数器值减1,值为1.
[stu release];
// 引用计数器值减1,值为0.
[stu release];
// 野指针错误.
[stu release];
}
return 0;
}
《OC10-内存管理2-set方法的内存管理》学习总结
1、基本数据类型不需要内存管理。
2、只要调用了alloc,必须有release或autorelease。
3、pragma mark注释,pragma mark-分类注释。
4、set示例。
#import "Student.h"
@implementation Student
- (id)initWithAge:(int)age {
if ( self = [super init] ) {
_age = age;
}
return self;
}
- (void)setBook:(Book *)book {
if (_book != book) {
// 先释放旧的成员变量
[_book release];
// 再retain新传进来的对象
_book = [book retain];
}
}
@end
《OC11-@class关键字》学习总结
1、引用一个类有两种方式:一种是通过#import方式引入,一种是通过@class引入。
2、#import方式会包含被引用类的所有信息,包括被引用类的变量和方法。
3、@class方式仅仅告诉编译器这是一个类。
4、使用@class方式在实现类时需要使用#import来包含被引用类的头文件。
5、如果很多文件都#import了同一个文件,会使效率大大降低,而使用@class方式不会出现这种问题。
6、对于循环依赖关系来说,无法使用#import方式,只能使用@class方式。
7、如果是集成某个类,就要导入类的头文件,如果只是定义成员变量、属性,用@class。
8、class示例。
#import <Foundation/Foundation.h>
// B是一个类.
@class B;
@interface A : NSObject
// b是B类的一个对象.
@property B *b;
@end
#import <Foundation/Foundation.h>
// A是一个类.
@class A;
@interface B : NSObject
// a是A类的一个对象.
@property A *a;
@end
《OC12-内存管理3-@property参数详解》学习总结
1、声明property的语法为:@property(参数1,参数2)类型 名字。
2、@property参数主要分为三类:读写属性、Setter语意、原子性。
3、读写属性:产生setter方法和getter方法(readwrite)、只产生getter方法,不产生setter方法(readonly)。
4、setter语意:setter方法直接赋值而不进行retain操作(assign)、setter方法对参数进行release旧值再retain新值(retain)。
5、原子性:setter方法进行Copy操作,与retain一样(copy)、禁止多线程,变量保护,提高性能(nonatomic)。
6、@property参数示例。
#import <Foundation/Foundation.h>
@class Book;
@class Card;
@interface Student : NSObject
// 这里的retain代表:在set方法中,release旧值,retain新值
@property (nonatomic, retain) Book *book;
@property (retain) Card *card;
// readonly代表只生成get方法的声明
// 默认是readwrite,同时生成get和set方法的声明
@property (readonly) int age;
// atomic就代表给方法进行加锁,保证线程安全
@property (atomic) int no;
// nonatomic代表方法不需要考虑线程安全问题
@property (nonatomic, assign) int no2;
// getter是用来指定get方法的方法名
@property (nonatomic, getter = isRich) BOOL rich;
@end
《OC13-内存管理4-autorelease》学习总结
1、自动释放池是OC里面的一种内存自动回收机制,一般可以将一些临时变量添加到自动释放池中,统一回收释放。
2、当自动释放池销毁时,里面的所有对象都会调用一次release方法。
3、OC对象发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中。
4、autorelease实际只是把对release的调用延迟了。
5、@autoreleasepool代表创建一个自动释放池。
6、不要把大量循环操作放到同一个自动释放池中,因为这样会造成内存峰值的上升。
7、尽量避免对大内存使用自动释放池,对于这种延迟释放机制,还是尽量少用,小内存则影响不大。
8、利用静态方法创建并返回的对象都是已经autorelease的,不需要在进行release操作。
9、autorelease的好处:不用再关心对象的释放时间,不用再关心什么时候调用release。
10、调用了autorelease后又调用release或连续调用autorelease都会产生野指针错误。
11、自动释放池是以栈结构存在的,当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池。
12、autorelease示例。
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[])
{
// 创建一个自动释放池
@autoreleasepool {
// 这个stu是自动释放的,不需要释放
Student *stu = [[[Student alloc] init] autorelease];
}
return 0;
}