main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc,const char * argv[]) {
@autoreleasepool {
// insert code here...
/*
// alloc的功能有两个:1、开辟内存空间,2、让对象的引用计数由0变为1
Person *person = [[Person alloc]init];
// 系统提供retainCount方法用来计算对象的引用计数;计算 出来的结果只能作为参考,不能用于正式开发
NSLog(@"person,count = %lu",[person retainCount]);
// retain使对象的引用计数加1
[person retain];
NSLog(@"person.count+1 = %lu",[person retainCount]);
// 对一个对象发送copy消息,对象就会找到copywithzone:方法并且执行;
// copy原理是生成一个新的对象,并且使新对象的引用计数变为1,不改变原始对象及引用计数
Person *p1 = [person copy];
NSLog(@"person.count = %lu",[person retainCount]);
// 让引用计数减1
[person release];
NSLog(@"person.count = %lu",[person retainCount]);
// 再执行一次release方法,person指向的堆区的内存,引用计数变为0;当对象的引用计数为0时,会自动调用dealloc方法,释放内存
[person release];
// 安全释放,当堆区内存被系统回收之后,栈区的变量还能找到被释放的内存,这个时候出现的问题就是野指针问题,防止野指针出现,就是将栈区存变量还保留的地址赋为空
person = nil;
// NSString *s = [[NSString alloc ]init];
// NSLog(@"s.count = %lu",[s retainCount]);
*/
//自动释放池
/*
Person *p = [[Person alloc] init];
NSLog(@"p.retaincount = %lu",[p retainCount]);
[p retain];
[p retain];
// autorelease方法也能使对象的引用计数减1,但是它不能让对象的引用计数立即减1,而是在未来的某一时刻减1;就是遇见自动释放池,而且自动释放池对象被释放
[p autorelease];
// 创建一个自动释放池对象;在ios5.0之后推荐使用@autorelease{};
NSAutoreleasePool *autoPool = [[NSAutoreleasePool alloc]init];
// 对p发送自动释放消息,p被放到离他最近的自动释放池中,
[p autorelease];
// 自动释放池对象被释放时,他里面等待被释放的对象就会被释放,引用计数都会减1
[autoPool release];
NSLog(@"p.retaincount = %lu",[p retainCount]);
// 在ios中能够使引用计数增加的方法:alloc,retain,copy
// 使引用计数减少的方法:release,autorelease
// 释放内存的方法:dealloc
*/
/*
// 通过new方法创建对象,合并了alloc和init
Person *per = [Person new];
NSLog(@"per = %lu",[per retainCount]);
Person *p1 = [[Person alloc]init];
NSString *name = [NSString stringWithFormat:@"张丹"];
p1.name = name;
Person *p2 = [p1 copy];
NSLog(@"p1.name = %@ p2.name = %@",p1.name,p2.name);
*/
// 数组的内存管理
/*
// 当对象创建出来,对象的引用计数 变成1
NSLog(@"p1.count = %lu p2.count = %lu",[p1 retainCount],[p2 retainCount]);
// 把对象放到数组中对象的引用计数加1
NSArray *array = [NSArray arrayWithObjects:p1,p2, nil];
NSLog(@"p1.count = %lu p2.count = %lu",[p1 retainCount],[p2 retainCount]);
[p1 release];
[p2 release];
// 将对象再次放到数组中,对象的引用计数再加1
NSMutableArray *muArray = [[NSMutableArray alloc] initWithArray:array];
NSLog(@"p1.count = %lu p2.count = %lu",[p1 retainCount],[p2 retainCount]);
// 将对象从数组中移除,对象的引用计数减1
[muArray removeObject:p1];
NSLog(@"p1.count = %lu p2.count = %lu",[p1 retainCount],[p2 retainCount]);
// [p1 release];
// [p2 release];
// 将数组对象释放掉,数组中的所有元素的引用计数都减1
[muArray release];
NSLog(@"p1.count = %lu p2.count = %lu",[p1 retainCount],[p2 retainCount]);
[p1 release];
[p2 release];
*/
Person *pers = [PersonpersonWithName:@"lisi"Sex:@"男"Age:44];
// [pers release];
}
return0;
}
Person.h
#import <Foundation/Foundation.h>
//只有遵守NSCopying协议,并且实现了协议里面的方法之后,才能接收copy;在ios里面只有NSObject这个类没有遵守NSCopying协议,其他的类都遵守NSCopying协议
@interface Person : NSObject <NSCopying>
//声明属性
@property (nonatomic,retain)NSString *name;
@property (nonatomic,retain)NSString *sex;
@property (nonatomic,assign)NSInteger age;
//声明自定义初始化方法
-(instancetype)initWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age;
//声明便利构造器方法
+(instancetype)personWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age;
@end
Person.m
#import "Person.h"
@implementation Person
//重写dealloc, dealloc方法不能手动调用
-(void)dealloc {
[_namerelease];
[_sexrelease];
NSLog(@"被释放了");
[superdealloc];
}
//减号方法中的self表示的是当前调用这个方法的对象
-(id)copyWithZone:(NSZone *)zone {
Person *p = [[PersonallocWithZone:zone]init];
// 成员变量的指针只是赋值,指向的是同一块内存;叫做浅拷贝
// p.name = self.name;
// 深拷贝,重新分配内存,将原来内存中的内容放到新分配的内存中
p.name = [[NSStringalloc]initWithFormat:@"%@",self.name];
return p;
}
//实现自定义初始化方法
-(instancetype)initWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age{
self = [superinit];
if (self) {
_name = name;
_sex = sex;
_age = age;
}
returnself;
}
//实现便利构造器方法
+(instancetype)personWithName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age{
return [[[selfalloc] initWithName:nameSex:sex Age:age]autorelease];
}
@end