标签:style blog http io color ar 使用 sp java
Objective-C的内存基本管理
在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;
-
- @end
Book.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];
- }
-
- @end
Student.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;
-
- @end
Student.m文件
- #import "Student.h"
- #import "Book.h"
-
- @implementation Student
-
- @synthesize age = _age;
- @synthesize book = _book;
-
- - (void)setBook:(Book *)book {
- if(_book != book){
-
-
- [_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 charchar * argv[]) {
- @autoreleasepool {
-
- Student *stu = [[Student alloc] initStudent:21];
-
- buyBook(stu);
-
- readBook(stu);
-
- [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的学生被释放了
@class关键字
通常引用一个类有两种方法,一种是通过#import,另一种是通过@class.
#import 的方式会将头文件中的所有信息引入。
@class 的方式只是说明它是一个类(假如只是声明一个类就不用使用#import).
- #import <Foundation/Foundation.h>
-
- @class 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;
- [_book release];
- NSLog(@"年龄为%d的学生被释放了", _age);
- [super dealloc];
- }
self.book = nil; 会调用setter方法,释放对象并将当前类Student的属性_book设为nil.
@property的参数
@property的参数格式: @property (参数1, 参数2,...) 类型 名字;
参数主要分为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;
-
- @interface Student : NSObject
- @property (nonatomic, assign, getter=getStudentAge) int age;
- @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;
- [_book release];
- NSLog(@"年龄为%d的学生被释放了", _age);
- [super dealloc];
- }
-
- @end
自动释放池
自 动释放池是OC里面的一种内存自动回收机制,一般可以将一些临时变量添加到自动释放池中,统一回收释放。当自动释放池销毁时,池里的所有对象都会调用一次 release方法。OC对象只需要发送一条autorelease消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池)。
autorelease实际上只是把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;
- [_book release];
- NSLog(@"年龄为%d的学生被释放了", _age);
- [super dealloc];
- }
-
- @end
- int main(int argc, const charchar * argv[]) {
-
- @autoreleasepool {
-
- Student *stu = [[[Student alloc] initStudent:21] autorelease];
- Student *stu1 = [[[Student alloc] initStudent:21] autorelease];
-
- }
-
- @autoreleasepool {
-
- Student *stu2 = [[Student alloc] initStudent:21];
-
- [stu2 autorelease];
- }
- @autoreleasepool {
-
-
- Student *stu3 = [Student student];
- }
- return 0;
Objective-C基础笔记(3)OC的内存管理
标签:style blog http io color ar 使用 sp java
原文地址:http://www.cnblogs.com/lkda992/p/4096341.html