标签:objective-c 内存管理 自动释放池 class关键字
在OC中每个变量都保存着引用计数器,当这个对象的引用计数器为0的时候该对象会被回收。当使用alloc、new或者copy创建一个对象的时候,对象的引用计数器被置为1.
给对象发送一条retain消息,可以使引用计数器+1.
给对象发送一条release消息,可以使引用计数器-1.
当OC被销毁的时候会发送一条dealloc消息(不要直接调用,由系统调用),可以重写dealloc方法,在该方法中释放相关资源。
可以给对象发送retainCount消息获取对象的当前引用计数器。
首先我们新建一个工程
接下来将工程的设置里面将ARC禁掉
Book.h文件
#import <Foundation/Foundation.h> @interface Book : NSObject @property float price; - (id)initBook:(float)price; @endBook.m文件
#import "Book.h"
@implementation Book
@synthesize price = _price;
//构造函数
- (id)initBook:(float)price {
if(self = [super init]){
_price = price;
}
NSLog(@"价格是%f的书购买了", _price);
return self;
}
//析构函数
- (void)dealloc {
NSLog(@"价格为%f的书被释放了", _price);
[super dealloc];
}
@endStudent.h文件#import <Foundation/Foundation.h> #import "Book.h" @interface Student : NSObject @property int age; @property Book *book; - (void)setBook:(Book *)book; - (id)initStudent:(int)age; @endStudent.m文件
#import "Student.h"
#import "Book.h"
@implementation Student
@synthesize age = _age;
@synthesize book = _book;
- (void)setBook:(Book *)book {
if(_book != book){
//先对原来的书计数器减一
//如果之前为nil不会出错(和java中的空指针不同)
[_book release];
[book retain];
_book = book;
}
}
//构造函数
- (id)initStudent:(int)age {
if(self = [super init]) {
_age = age;
}
NSLog(@"年龄为%d的学生被创建了", _age);
return self;
}
//析构函数
- (void)dealloc{
[_book release];
NSLog(@"年龄为%d的学生被释放了", _age);
[super dealloc];
}
@end
main.m文件#import <Foundation/Foundation.h>
#import "Student.h"
#import "Book.h"
void buyBook(Student *stu) {
Book *book1 = [[Book alloc] initBook:101.5]; //谁创建谁释放
stu.book = book1;
[book1 release];
Book *book2 = [[Book alloc] initBook:98.5];
stu.book = book2;
[book2 release];
}
void readBook(Student *stu) {
NSLog(@"年龄是%i的学生在读价格为%f的书", stu.age, stu.book.price);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
//计数器为1
Student *stu = [[Student alloc] initStudent:21];
//买书
buyBook(stu);
//看书
readBook(stu);
//计数器清0,释放内存
[stu release];
}
return 0;
}
输出结果:2014-11-13 23:11:19.510 内存管理[698:46519] 年龄为21的学生被创建了
2014-11-13 23:11:19.512 内存管理[698:46519] 价格是101.500000的书购买了
2014-11-13 23:11:19.512 内存管理[698:46519] 价格是98.500000的书购买了
2014-11-13 23:11:19.512 内存管理[698:46519] 价格为101.500000的书被释放了
2014-11-13 23:11:19.512 内存管理[698:46519] 年龄是21的学生在读价格为98.500000的书
2014-11-13 23:11:19.512 内存管理[698:46519] 价格为98.500000的书被释放了
2014-11-13 23:11:19.512 内存管理[698:46519] 年龄为21的学生被释放了
#import 的方式会将头文件中的所有信息引入。
@class 的方式只是说明它是一个类(假如只是声明一个类就不用使用#import).
#import <Foundation/Foundation.h>
@class Book; //声明Book是一个类
@interface Student : NSObject {
Book *_book;
}
@property int age;
@property Book *book;
- (void)setBook:(Book *)book;
- (id)initStudent:(int)age;
@end另外,Student.m中的析构函数我们可以做如下修改//析构函数
- (void)dealloc{
self.book = nil; //调用setter方法
[_book release];
NSLog(@"年龄为%d的学生被释放了", _age);
[super dealloc];
}self.book = nil; 会调用setter方法,释放对象并将当前类Student的属性_book设为nil.参数主要分为3类:
读写属性:readwrite / readonly
setter处理: assign / retain / copy
原子性:atomic / nonatomic
说明:
readonly代表只生成getter方法,默认是readwrite
assing默认(直接赋值),copy是setter方法release旧值,再copy新值
atomic(默认),保证getter和setter的原子性,提供多线程安全访问,nonatomic性能高,所以一般是选择nonatomic.
#import <Foundation/Foundation.h> @class Book; //声明Book是一个类 @interface Student : NSObject //assign参数代表set方法直接赋值(默认的) //getter方法是指定getter方法的名字 @property (nonatomic, assign, getter=getStudentAge) int age; //这里的retain代表:release旧值,retain新值 //(注意,基本数据类型不能写retain参数) @property (nonatomic, retain) Book *book; - (void)setBook:(Book *)book; - (id)initStudent:(int)age; @end
#import "Student.h"
#import "Book.h"
@implementation Student
//构造函数
- (id)initStudent:(int)age {
if(self = [super init]) {
_age = age;
}
NSLog(@"年龄为%d的学生被创建了", _age);
return self;
}
//析构函数
- (void)dealloc{
self.book = nil; //调用setter方法
[_book release];
NSLog(@"年龄为%d的学生被释放了", _age);
[super dealloc];
}
@endautorelease实际上只是把release的调用延迟了,对于每一次autorelease,系统只是把该对象放入当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会调用一次release方法。
#import "Student.h"
#import "Book.h"
@implementation Student
//创建静态方法构造对象
+ (id)student {
Student *stu = [[[Student alloc] init] autorelease];
return stu;
}
//创建带参数的静态方法构造对象
+ (id)studentWithAge:(int)age {
Student *stu = [self student];
stu.age = age;
return stu;
}
//构造函数
- (id)initStudent:(int)age {
if(self = [super init]) {
_age = age;
}
NSLog(@"年龄为%d的学生被创建了", _age);
return self;
}
//析构函数
- (void)dealloc{
self.book = nil; //调用setter方法
[_book release];
NSLog(@"年龄为%d的学生被释放了", _age);
[super dealloc];
}
@endint main(int argc, const char * argv[]) {
//代表创建一个自动释放池
@autoreleasepool {
//第一种写法
Student *stu = [[[Student alloc] initStudent:21] autorelease];
Student *stu1 = [[[Student alloc] initStudent:21] autorelease];
} //当括号结束后,池子将被销毁
//如果自动释放池被销毁,池里面的所有对象都会调用release方法
@autoreleasepool {
//第二种写法
Student *stu2 = [[Student alloc] initStudent:21];
[stu2 autorelease];
}
@autoreleasepool {
//第三种写法(推荐)
//不用手动释放
Student *stu3 = [Student student];
}
return 0;
}标签:objective-c 内存管理 自动释放池 class关键字
原文地址:http://blog.csdn.net/dawanganban/article/details/41087957