#import <Foundation/Foundation.h> #import "Person.h" #import "OurClass.h" #import "Student.h" int main(int argc, const char * argv[]) { @autoreleasepool { // //创建 OurClass 和 Person 对象 // OurClass *myClass = [[OurClass alloc] init]; // Person *per = [[Person alloc] initWithName:@"蒙多" sex:@"男" age:20]; // // myClass.person = per; //相当于myClass.person = [per copy]; 当属性为 retain 时,相当于myClass.person = [per retain]; 当属性为assign时,相当于直接赋值; // NSLog(@"%lu",[per retainCount]); // //// [per release]; // // 属性是 assign 时: 当 per释放后,myClass.person是直接赋值的,所以此时它会变成野指针.这就是为何当实例变量是对象的时候为什么不用 assign 的原因. // // 属性是 copy 时: 当 per释放后,myClass.person是新的对象,所以当销毁之前对象时,此时不会影响 // // 属性是 retain 时: 当 per释放后,myClass.person是持有那个对象的一个所有权,所以当销毁之前对象时,此时不会影响 // // // // // ////便利构造器 // // Person *per1 = [Person personWithName:@"lisi " sex:@"mele" age:22]; // //便利构造器中放置 autorelease 结束后自动释放 // NSLog(@"%lu",[per1 retainCount]); // // // //// 集合的内存管理 // // Person *per2 = [Person personWithName:@"lvsheng" sex:@"male" age:15]; // NSLog(@"%lu",[per2 retainCount]); // // /* // 1.集合会自己管理自己的元素对象,不需要我们管理. // 2.集合添加元素 会对该对象进行引用计数 + 1 (相当于retain一次) // 3.集合移除元素 会对该对象进行引用计数 - 1 (相当于release一次) // // */ // // //创建数组对象 // NSMutableArray *arr = [[NSMutableArray alloc]init]; // // //数组添加元素 会对该对象进行引用计数 + 1 (相当于retain一次) // [arr addObject:per2]; // NSLog(@"%lu",[per2 retainCount]); // // //数组移除元素 会对该对象进行引用计数 - 1 (相当于release一次) // [arr removeObject:per2]; // NSLog(@"%lu",[per2 retainCount]); // // // //创建字典 // NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; // // //字典添加元素 会对该对象进行引用计数 + 1 (相当于retain一次) // [dic setValue:per2 forKey:@"person"]; // NSLog(@"%lu",[per2 retainCount]); // // // //创建集合 // NSMutableSet *set = [[NSMutableSet alloc] init]; // // //集合添加元素 会对该对象进行引用计数 + 1 (相当于retain一次) // [set addObject:per2]; // NSLog(@"%lu",[per2 retainCount]); // //集合 copy 问题 //可以理解为集合的 copy 都是 assign 的直接赋值的 Person *per = [[Person alloc] init]; //0~1 NSMutableArray *arr = [[NSMutableArray alloc] init]; [arr addObject:per]; //1~2 NSMutableArray *arr1 = [arr copy]; //2~3 NSLog(@"%lu",[per retainCount]); Person *per1 = arr[0]; Person *per2 = arr1[0]; //打印出来地址相同,所以证明可变数组的 copy 是浅拷贝 NSLog(@"%p,%p",per1,per2); NSArray *array = [[NSArray alloc] initWithObjects:per, nil]; NSLog(@"%lu",[per retainCount]); //3~4 NSArray *array1 = [array copy]; NSLog(@"%lu",[per retainCount]); // 4 //地址相同,不可变数组 copy 也使浅拷贝 NSLog(@"%p,%p",array[0],array1[0]); //多态 //父类指针可以指向子类对象,可以写出我们通用的代码 addSubView:(UIView *)view 方法,需要传入的参数可以是 UIView 对象以及 UIView 子类对象 Person *per_1 = [[Student alloc] init]; } return 0; }
<OurClass.h>
#import <Foundation/Foundation.h> #import "Person.h" @interface OurClass : NSObject { Person *_person; } //@property (nonatomic,assign)Person *person; //@property (nonatomic,copy)Person *person; @property (nonatomic,retain)Person *person; @end
<OurClass.m>
#import "OurClass.h" @implementation OurClass /* //assign -(void)setPerson:(Person *)person { _person = person; } -(Person *)person { return _person; } */ /* //copy -(void)setPerson:(Person *)person { //判断当前传入的对象是否是已经持有的对象 if (_person != person) { //释放之前的所有权 [_person release]; //操作 copy 对新的对象持有所有权 _person = [person copy]; } } */ //retain -(void)setPerson:(Person *)person { //判断当前传入的对象是否是已经持有的对象 if (_person != person) { //释放之前的所有权 [_person release]; //操作 retain ,获取新的持有所有权 _person = [person retain]; } } //dealloc -(void)dealloc { //在当前对象销毁时,释放自身实例变量持有的对象所有权 // [_person release]; // _person = nil; self.person = nil; //此一步代替上面两步 NSLog(@"OurClass 类的对象被销毁了"); [super dealloc];//销毁时 } @end
<Person.h>
#import <Foundation/Foundation.h> @interface Person : NSObject <NSCopying> { NSString *_name; NSString *_sex; NSInteger _age; } @property (nonatomic,copy)NSString *name; @property (nonatomic,retain)NSString *sex; //如果不怕其自身别修改的话,可以用 retain @property (nonatomic)NSInteger age; -(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age; +(Person *)personWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age; -(void)dealloc; @end
<Person.m>
#import "Person.h" @implementation Person -(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age { if ([super init]) { _name = name; _sex = sex; _age = age; }return self; } +(Person *)personWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age { //对于遍历构造器内部 我们不进行内存管理,会造成内存泄露,如果 release 了,又会野指针问题,所以我们使用 autorelease, 最佳方案 return [[[Person alloc] initWithName:name sex:sex age:age] autorelease]; } //assign -(void)setAge:(NSInteger)age { _age = age; } //retain -(void)setSex:(NSString *)sex { if (_sex != sex) { [_sex release]; _sex = [sex retain]; } } //copy -(void)setName:(NSString *)name { if (_name != name) { [_name release]; _name = [name copy]; } } -(id)copyWithZone:(NSZone *)zone { Person *temp = [[Person alloc] init]; temp.name = self.name; temp.sex =self.sex; temp.age = self.age; return temp; } -(void)dealloc { //释放自身实例变量持有权,再释放父类的 self.name = nil; self.sex = nil; NSLog(@"Person类的对象被销毁了"); [super dealloc]; } @end
<Student.h>
#import "Person.h" @interface Student : Person { NSNumber *_number; } @property (nonatomic,retain)NSNumber *number; -(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number; +(Student *)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number; -(void)dealloc; @end
<Student.m>
#import "Student.h" @implementation Student -(id)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number { if ([super initWithName:name sex:sex age:age]) { _number = number; }return self; } +(Student *)studentWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age munber:(NSNumber *)number { return [[[Student alloc] initWithName:name sex:sex age:age munber:number] autorelease]; } -(void)setNumber:(NSNumber *)number { if (_number != number) { [_number release]; _number = [number retain]; } } -(NSNumber *)number { return _number; } -(void)dealloc { self.number = nil; NSLog(@"Student 类的对象被销毁了"); [super dealloc]; } @end