OC - Menory(High)

<main.m>
#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



你可能感兴趣的:(copy,内存管理,assign,retain,release)