OC08,09_内存管理

来源:互联网 发布:java io总结 编辑:程序博客网 时间:2024/05/16 01:50

//

//  main.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Girl.h"

#import "Boy.h"

#import "Person.h"

int main(int argc,constchar * argv[]) {


//    Boy *boy=[[Boy alloc] init];

//    Girl *girl=[[Girl alloc] init];

//    girl.delegate=boy;

//    [girl getMarry];



    ////内存管理,管理内存有三种方式,

    //1.垃圾回收,java常见的内存管理方法,系统来检测对象是否被使用,是否被释放

    //2.MRC手动管理引用计数,iOS管理内存的方式,程序员通过手动方式来管理对象是否被释放

    //3.ARC自动管理引用计数,基于MRC,系统自动管理内存,以后我们还是先使用MRC,培养管理内存的习惯..

    //对象被创建出来后他的引用计数retainCount就变成了1

    ////************************ 1

//    Boy *boy=[[Boy alloc] init];

//    NSLog(@"%ld",boy.retainCount);

//    ///retain:对对象的引用计数进行加1的操作

    ////***************************2.

//    [boy retain];

//    NSLog(@"%ld",boy.retainCount);

//    [boy retain];

//    [boy retain];

//    NSLog(@"%ld",boy.retainCount);

//    ///release:对对象的引用计数进行减一的操作

    ////*************************3.

//    [boy release];

//    NSLog(@"%ld",boy.retainCount);

//    [boy release];

//    [boy release];

//    [boy release];

//    NSLog(@"%ld",boy.retainCount);

    ////**************************4.dealloc

    //当对象的引用计数1->0的时候,会自动调用dealloc方法dealloc才是对应的对象释放的方法.

//当对象调用release的时候,他的引用计数是1,这个对象就不在对他的引用计数进行-1操作,而是直接调用dealloc方法,所以我们在访问对象引用计数还是1.

    //如果多次对对象进行释放,会造成过度释放,过度释放也是最常见的内存问题....

    //[boy release];//崩溃了,因为过度释放了..

    //NSLog(@"%ld",boy.retainCount);



//    NSArray *arr=@[@"1",@"2",@"3",@"4"];

//    NSLog(@"%ld",arr.retainCount);

//    NSString *str=@"11111";

//    NSLog(@"%ld",str.retainCount);

//    NSMutableString *str1=[NSMutableString stringWithString:@"11111"];

//    NSLog(@"%ld",str1.retainCount);

//    NSDictionary *dic=@{@"1":@"2",@"3":@"4"};

//    NSLog(@"%ld",dic.retainCount);


//    NSLog(@"%p",str);

//    NSLog(@"%p",str1);

//NSString的对象在全局静态区,他的引用计数是-1,代表正整数的最大值,其他的对象都在堆区


//    Boy *boy=[[Boy alloc] init];

//    [boy retain];

//    [boy retain];

//    NSLog(@"%ld",boy.retainCount);

    //release马上会把对象的引用计数-1,但是autorelease会延迟对对象的计数-1...

//    [boy release];

//    NSLog(@"%ld",boy.retainCount);

    //自动释放池

    //只要对象用autorelease释放会把对象放入到系统的自动释放池,等出了池子的范围,对象引用计数自动-1,这个相当于java的垃圾回收,对象释放由系统来管理

///    @autoreleasepool {

//        [boy autorelease];

//        NSLog(@"%ld",boy.retainCount);

///    }

//        NSLog(@"%ld",boy.retainCount);


//内存管理的原则:加多少,对应的减多少,加减做到对应平衡..


    //对象的所有权:拥有所有权的对象对可以对他进行release

//    Boy *b=[Boy boy];

//    [b retain];//1之后,,b有所有权.可以进行release

//    NSLog(@"%ld",b.retainCount);

//    [b release];

    //对象如果是我们进行alloc或者retain之后我们就获取了对象的所有权,就可以对对象进行release操作

    //便利构造器在返回对象的时候会加上一个autorelease,所以用便利构造器创建对象不用对内存进行管理


   // NSArray *arr1=[[NSArray alloc] initWithObjects:@"1",@"2", nil];

   // NSArray *arr2=[[NSArray alloc] initWithObjects:@"1",@"2", nil];

    //id是泛型指针,可以在任何方法中使用,但是instancetype代表实例类型,用在自定义初始化方法.便利构造器作为返回值类型使用,标示方法会返回一个对象回去..



//    NSArray *arr=@[@"1",@"2",@"3",@"4"];

//    NSLog(@"%ld",arr.retainCount);

    ////*****************************5.

//    //NSArray *newArr=[arr copy];

//    NSArray *newArr=[NSArray arrayWithArray:arr];

//    //NSArray *newArr=[[NSArray alloc] initWithArray:arr];

//    NSLog(@"%@",newArr);

//    NSLog(@"%ld",newArr.retainCount);

///不可变->可变

   //1.

    //NSMutableArray *arr1=[NSMutableArray arrayWithArray:arr];

    //2.使用mutableArray把不可变数组变成了可变数组

//    NSMutableArray *arr2=[arr mutableCopy];

//    [arr2 addObject:@"5"];

//    NSLog(@"%@",arr2);

    //将不可变的字典变成可变的字典..

//    NSDictionary *dic=@{@"1":@"2",@"3":@"4"};

//    NSMutableDictionary *muDic=[dic mutableCopy];

//    NSLog(@"%@",muDic);

///系统的类要是实现copy拷贝的功能,必须先签订拷贝NSCoping的协议,然后实现对应的方法

///不可变的数组字典可以通过mutableCopy转换成可变的数组字典.

///mutableCopy出来的对象是可变的,copy是不可变的


//用自己的类实现拷贝

//Boy类使用copy方法

//    Boy *boy=[Boy boyWithName:@"安逸臣" hobby:@""];

//    Boy *newboy=[boy copy];

//    NSLog(@"%@",newboy.name);


///自己的类想要实现copy的功能,就必须先签订NSCopying,然后实现对应的协议方法,initWithZone,之后就可以使用copy功能..

    //boy,newboy

//    NSLog(@"%ld",boy.retainCount);

//    NSLog(@"%ld",newboy.retainCount);

//copy也可以改变引用计数,但是他改变的是新对象的引用计数,而原来的对象计数不变..


//    Boy *boy1=[[Boy alloc] init];///1

//    //Boy *boy2=[[Boy alloc] init];

//    [boy1 retain];///2

//    [boy1 retain];///3

//    NSLog(@"%ld",boy1.retainCount);

    ///*********************5.

//    NSMutableArray *arr=[NSMutableArray arrayWithObjects:boy1, nil];///4

//    NSLog(@"%ld",boy1.retainCount);

//    //NSLog(@"%ld",[arr[0] retainCount]);

//    [arr removeObjectAtIndex:0];

//    NSLog(@"%ld",boy1.retainCount);

///当对象放入到容器Array或者字典中,对象被容器进行一次持有,就是retain一次,他的引用计数会加1,主要为了防止空指针问题

    //等对象从容器中移除掉后,相应得会减1


    //Boy *b=[[Boy alloc] init];

    //便利构造器不用管理内存..

    //NSArray *arr1=[NSArray arrayWithObjects:b, nil];//只要加入数组,对应各个元素引用计数加1.,随着数组的消失减1,释放

    //[b release];//对应alloc1.

///alloc<--->dealloc

///retain<--->release

    ////自己写多少个allocretain就对应写几个release进行释放....


//    Boy *b=[[Boy alloc] init];

//    Girl *girl=[[Girl alloc] init];

//    b.girls=girl;//boy.h文件   _girls=girl,,,未对_girls释放,,对其加1

//    NSLog(@"%ld",girl.retainCount);

//    Girl *girl2=[[Girl alloc] init];

//    b.girls=girl2;//boy.h文件  _girls!=girl,,_girls进行释放

//    NSLog(@"%ld",girl.retainCount);




//    Person *per=[Person personWithName:@"dsaf" age:20];

//    [per.arr addObject:@"1"];

//    NSLog(@"%@",per.arr);



   NSString *name = [[NSStringalloc]initWithFormat:@"张三"];

   Person *p = [[Personalloc]init];

    [psetName:name];

    [namerelease];

   NSLog(@"%@",[pname]);

   NSString *newName = [[NSStringalloc]initWithFormat:@"李四"];

    [psetName:newName];

    [newNamerelease];

   NSLog(@"%@",[pname]);

    [prelease];

   

   return0;

}



////////////////////////Girl/////////////////////////////////////////

(1)//

//  Girl.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import <Foundation/Foundation.h>

//1.声明协议

@protocol GirlDelegate <NSObject>

@required//必须执行的

-(void)married;

@optional//,,可执行的,可不执行的

-(void)cook;


@end

@interface Girl : NSObject

//2.声明代理人属性

@property(nonatomic,assign)id<GirlDelegate>delegate;

-(void)getMarry;

@end



(2)//

//  Girl.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import "Girl.h"


@implementation Girl

-(void)getMarry{

    //3.设置代理人执行的方法

    [self.delegatemarried];

    [self.delegatecook];

}


@end



///////////////Boy///////////////////////

(1)//

//  Boy.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Girl.h"

@interface Boy : NSObject<GirlDelegate,NSCopying>


@property(nonatomic,retain)NSString *name;

@property(nonatomic,retain)Girl *girls;

@property(nonatomic,copy)NSString *hobby;

//自定义初始化方法

-(instancetype)initWithName:(NSString *)name

                      hobby:(NSString *)hobby;

+(Boy *)boyWithName:(NSString *)name

              hobby:(NSString *)hobby;



//id->void *





+(Boy *)boy;


@end



(2)//

//  Boy.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import "Boy.h"


@implementation Boy

-(void)cook{

   NSLog(@"做饭吃");

}

-(void)married{

    NSLog(@"咱们结婚吧");


}

-(void)dealloc{

    NSLog(@"对象被释放了");

    //把成员变量里的+1操作全部减掉

    [_namerelease];

    [_girlsrelease];

    [_hobbyrelease];

    [superdealloc];

}


//刚创建就释放,返回的指针是野指针

+(Boy *)boy{

   Boy *b=[[Boyalloc]init];

    return [bautorelease];

}


//自己的类实现copy

- (id)copyWithZone:(NSZone *)zone{

   Boy *b=[BoyallocWithZone:zone];

    b.hobby=_hobby;

    b.name=_name;

   return b;

}



//自定义初始化

-(instancetype)initWithName:(NSString *)name

                      hobby:(NSString *)hobby{

   self=[superinit];

   if (self) {

       self.name=name;

       self.hobby=hobby;

    }

    return self;

}



//便利构造器

+(Boy *)boyWithName:(NSString *)name

              hobby:(NSString *)hobby{

   Boy *b=[[Boyalloc]initWithName:namehobby:hobby];

    ///写便利构造器最后别忘了autorelease

    return [bautorelease];

}



-(void)setName:(NSString *)name{

    ///1.

   if (_name!=name) {

        [_namerelease];

       _name=[nameretain];

    }

    ///2.

//    [name retain];

//    [_name release];

//    _name=name;



}



@end



///////////////Person////////////

(1)//

//  Person.h

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import <Foundation/Foundation.h>


@interface Person :NSObject

@property(nonatomic,retain)NSMutableArray *arr;

@property(nonatomic,copy)NSString *name;

@property(nonatomic,assign)NSInteger age;


-(id)initWithName:(NSString *)name

                age:(NSInteger)age;

+(Person *)personWithName:(NSString *)name

                age:(NSInteger)age;

@end



(2)//

//  Person.m

//  OC08,09_内存管理

//

//  Created by dllo on 15/7/27.

//  Copyright (c) 2015 flg. All rights reserved.

//


#import "Person.h"


@implementation Person

-(id)initWithName:(NSString *)name

                age:(NSInteger)age{

   self=[superinit];

   if (self) {

        self.name=name;//************(copy)有优化

        self.age=age;//***************(assign)没有优化

        //_age=age....age不是retain类型没有优化

        //对象创建后,里面的数组也会创建好,不在外面进行创建,避免因为忘了造成问题

        self.arr=[NSMutableArrayarray];//**************(retain)有优化

    }

    return self;

}

+(Person *)personWithName:(NSString *)name

                age:(NSInteger)age{

   Person *per=[[Personalloc]initWithName:nameage:age];

   return [perautorelease];


}


-(void)dealloc{

    [_arrrelease];

    [_namerelease];

    [superdealloc];

}


@end









0 0
原创粉丝点击