// // main.m // Set方法的内存管理 #import <Foundation/Foundation.h> #import "Person.h" #import "Room.h" int main(int argc, const char * argv[]) { @autoreleasepool { // 1.创建两个对象 Person *p = [[Person alloc] init]; Room *r = [[Room alloc] init]; r.no = 888; NSLog(@"%lu",[r retainCount]); // 2.将房间赋值给人 // 人需要使用这间房, 只要人在房间就一定要在 p.room = r; // [p setRoom:r] p.room = r; // [p setRoom:r] p.room = r; // [p setRoom:r] p.room = r; // [p setRoom:r] NSLog(@"%lu",[r retainCount]); [r release]; // 3.换房 Room *r2 = [[Room alloc] init]; r2.no = 444; // 有问题 p.room = r2; [r2 release]; // 在这行代码之前, 人都没有被释放 NSLog(@"-----"); // 3,人都不在了, 房间也必须销毁 [p release]; } return 0; }
// // Person.h #import <Foundation/Foundation.h> #import "Room.h" @interface Person : NSObject { Room *_room; } - (void)setRoom:(Room *)room; - (Room *)room; @end
// // Person.m #import "Person.h" @implementation Person // 当A对象想使用B对象一定要对B对象进行一次retain, 这样才能保证A对象存在B对象就存在, 也就是说这样才能保证无论在什么时候在A对象中都可以使用B对象 // 当A对象释放的时候, 一定要对B对应进行一次release, 这样才能保证A对象释放了, B对应也会随之释放, 避免内存泄露 // 总结一句话: 有增就有减 - (void)setRoom:(Room *)room // room = r { // 只有房间不同才需用release和retain if (_room != room) {// 0ffe1 != 0ffe1,防止了相同的set会加多次, // 将以前的房间释放掉 -1,更换room的时候将之前的room的计数器减一, [_room release]; /* 对房间的引用计数器+1 [room retain]; _room = room; */ // retain不仅仅会对引用计数器+1, 而且还会返回当前对象 _room = [room retain]; } } - (Room *)room { return _room; } - (void)dealloc { // 人释放了, 那么房间也需要释放 [_room release]; NSLog(@"%s", __func__); [super dealloc]; } @end
// Room.h #import <Foundation/Foundation.h> @interface Room : NSObject @property int no;// 房间号 @end
// Room.m #import "Room.h" @implementation Room - (void)dealloc { NSLog(@"%s no = %i", __func__, _no); [super dealloc]; } @end