您的位置:首页 > 其它

OC - Memory

2015-08-14 20:16 253 查看
<main.m>

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{

@autoreleasepool {

//--------------------------------------retain-------------------------------

//创建 person 类对象
Person *per1 = [Person personWithName:@"张三" sex:@"男" age:@"22"];

//retain 获取对象的引用计数
NSLog(@"per1:%lu",[per1 retainCount]); // 1

//retain 将对象的引用计数 + 1
Person *per2 = [per1 retain];  //   1  +  1
NSLog(@"per1:%lu",[per1 retainCount]);
NSLog(@"per2:%lu",[per2 retainCount]);

Person *per3 = [per2 retain];  //   1   +  2
NSLog(@"per1:%lu",[per1 retainCount]); // 1
NSLog(@"per2:%lu",[per2 retainCount]);
NSLog(@"per3:%lu",[per3 retainCount]);

//release 引用计数 - 1
[per3 release];
per3 = nil;//注意野指针问题,当指针放弃对对象的特有权,将指针变量置为 nil;
NSLog(@"%lu",[per2 retainCount]);//  3  -  1

[per2 release];
per2 = nil;
NSLog(@"%lu",[per1 retainCount]); //  2 - 1

//当对象的引用计数1~0,系统立即自动调用 dealloc 销毁对象,不允许手动调用 dealloc
[per1 release];
per1 = nil;       //retain ,放弃对象操作的特有权.
NSLog(@"%lu",[per1 retainCount]);// tetain 最小为1.

//过度释放问题,
//        [per1 release];
//        NSLog(@"%lu",[per1 retainCount]);

//系统中定得类型  ,nsarry 自动默认为2,添加元素后为1
NSArray *arr = [[NSArray alloc] init ];
NSLog(@"%lu",[arr retainCount]);  //    2
//常量
NSString *str = @"test";
NSLog(@"%lu",[str retainCount]);

//自动释放
Person *per = [[Person alloc] init];// 0 ~ 1
[per retain];  //1 ~ 2
NSLog(@"%lu",[per retainCount]);

// 1\       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

//相当于前和后 1\ 和2\ 的两行代码
@autoreleasepool {

/*
autorelease 将被修饰的对象放入离他最近的自动释放池内,当自动释放池自身销毁时,会对它内部所有的对象,发送一条release消息.(!!!而不是销毁操作)
一般使用于你不知道对象要使用多久.
##黄金法则:如果你对一个对象进行了 alloc retain copy 操作,你就拥有了该对象的所有权,你就有义务对其进行 release 和 autorelease 操作.##
*/

[per autorelease];//autorelease:未来的某⼀时刻引用计数减1.
NSLog(@"池子内%lu",[per retainCount]);
[per autorelease];  //之前的计数有多少次就能释放多少次
NSLog(@"池子内%lu",[per retainCount]);
}
//2\        [pool release];

NSLog(@"池子外%lu",[per retainCount]);

//--------------------------------------copy-------------------------------

Person *per_1 = [[Person alloc] initWithName:@"火车票" sex:@"?" age:@"-1"];
//如果对一个对象使用 copy 必须服从 NSCoping 协议并且实现 copyWithZone: 方法
//字符串是系统规定的服从这个协议之后的,所以我们可以直接使用
Person  *per_2 = [per_1 copy];
NSLog(@"per1:%lu",[per_1 retainCount]);
NSLog(@"per2:%lu",[per_2 retainCount]);

//        for(long i = 0;i < 100000000;i++){
//            @autoreleasepool {
//                Person *per4 = [[Person alloc]   init];
//
//                [per4 autorelease];
//
//            }
//        }

}
return 0;
}


<Person.h>

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCopying>

{
NSString *_name;
NSString *_sex;
NSString *_age;
}

@property (nonatomic,copy)NSString *name;
@property (nonatomic,copy)NSString *sex;
@property(nonatomic,copy)NSString *age;

-(id)initWithName:(NSString *)name
sex:(NSString *)sex
age:(NSString *)age;

+(Person *)personWithName:(NSString *)name
sex:(NSString *)sex
age:(NSString *)age;

//重写 dealloc
//-(void)dealloc;

@end


<Person.m>

#import "Person.h"

@implementation Person

-(id)initWithName:(NSString *)name
sex:(NSString *)sex
age:(NSString *)age
{
if ([super  init]) {
_name = name;
_sex = sex;
_age = age;
}return self;
}

+(Person *)personWithName:(NSString *)name
sex:(NSString *)sex
age:(NSString *)age
{
return [[Person alloc ] initWithName:name sex:sex age:age];
}

//重写 dealloc
-(void)dealloc
{
NSLog(@"对象被销毁");
[super dealloc];
}

//浅拷贝是直接赋值,相当于新建的指针指向之前的内容,而深拷贝是重新建立一个副本,进行 copy 操作,指针指向副本,retain
//深拷贝
-(id)copyWithZone:(NSZone *)zone
{
Person *per =[[Person alloc] init];
//实例变量的复制
per.name = self.name;
per.sex = self.sex;
per.age = self.age;
return per;
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: