OC基础——copy语法(Student属性的copy、Student对象的copy、Student子类对象的copy)

//
//  Student.h
//  copy语法2
//
//  Created by XinYou on 15-1-27.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import 
   
   
    
    

@interface Student : NSObject 
    
    
     
     

// copy代表name属性的set方法会release旧对象、copy新对象
// 修改外面的变量,并不会影响到内部的成员变量
// 建议:NSString一般用copy策略,其他对象一般用retain策略
@property (nonatomic, copy) NSString *name;

+ (id)studentWithName:(NSString *)name;


@end
//
//  Student.m
//  copy语法2
//
//  Created by XinYou on 15-1-27.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import "Student.h"

@implementation Student


+ (id)studentWithName:(NSString *)name{
    // 这里为什么要写成[self class],而不是Student?
    // 因为如果Student有一个子类GoodStudent,这里的[self class]就表示GoodStudent
    // 这样我们在子类中调用studentWithName的时候得到的就是子类对象,如果得到的是父类对象,程序会出错
    Student *stu = [[[[self class] alloc] init] autorelease];
    
    stu.name = name;
    
    return stu;
}

#pragma mark copying协议的方法
- (id)copyWithZone:(NSZone *)zone{

    // 这里创建的副本对象不要求释放。这是为什么呢?
    // 因为我们在其他的地方对Student对象进行copy操作时,得到的就是这个copyStu对象
    // 应该在copy操作之后再对copyStu进行release操作。
    // 如果在这里就对copyStu进行release操作,那么在其他地方得到的copyStu对象是已经被释放的对象。
    Student *copyStu = [[[self class] allocWithZone:zone] init];
    
    copyStu.name = self.name;
    
    return copyStu;

}

- (NSString *)description{
    
    // 特别注意:不能在description方法内部打印self,不然会造成死循环!!!
//    return [NSString stringWithFormat:@"Student = %@", self];
    
    return [NSString stringWithFormat:@"[name = %@]", _name];
}

- (void)dealloc{

    [_name release];

    [super dealloc];
}
@end
//
//  GoodStudent.h
//  copy语法2
//
//  Created by XinYou on 15-1-27.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import "Student.h"

@interface GoodStudent : Student

@property (nonatomic, assign) int age;

+ (id)goodStudentWithAge:(int)age name:(NSString *)name;

@end
//
//  GoodStudent.m
//  copy语法2
//
//  Created by XinYou on 15-1-27.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import "GoodStudent.h"

@implementation GoodStudent

+ (id)goodStudentWithAge:(int)age name:(NSString *)name{

    GoodStudent *goodStu = [GoodStudent studentWithName:name];
    
    goodStu.age = age;
    
    return goodStu;
}


- (id)copyWithZone:(NSZone *)zone{
    // 一定要调用父类的方法
    GoodStudent *copyStu = [super copyWithZone:zone];
    
    copyStu.age = self.age;
    
    return copyStu;
}

@end
//
//  main.m
//  copy语法2
//
//  Created by XinYou on 15-1-27.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import 
     
     
      
      
#import "Student.h"
#import "GoodStudent.h"

#pragma mark Student对象的name属性的copy
void studentNameCopy(){

    Student *stu = [Student studentWithName:@"zhangsan"];
    
    NSMutableString *str = [NSMutableString stringWithString:@"lisi"];
    /**
     Student中name属性的set方法:
     - (void)setName:(NSString *)name{
        if (_name != name){
            // 先释放旧的
            [_name release];
            // 再把新的赋值给_name
            _name = [name copy];// _name = [name retain];
        }
     }
     */
    
    // 因为Student的name属性采用的是copy策略,所以name属性的set方法如上所示
    // 当执行下面这句代码的时候:
    // 会对str这个字符串进行copy操作,产生一个副本(深拷贝),然后把这个副本(内存地址值)赋值给_name
    // 然后_name这个指针变量指向了@"lisi"这个字符串
    // 然后对str这个可变字符串进行appendString操作,改变的是str,并没有改变str的副本
    // 也就是说_name指向的字符串并没有发生改变
    
    // 如果Student的name属性采用的是retain策略,那么当执行下面这句代码的时候:
    // 会把str中存储的(内存地址)值赋值给_name,也就是说_name和str指向同一个字符串。
    // 然后对str这个可变字符串进行appendString操作,而_name的指向并没有发生改变
    // 也就相当于_name这个字符串也进行了appendString操作
    stu.name = str;
    
    [str appendString:@"wangwu"];
    
    NSLog(@"stu name is %@", stu.name);// stu name is lisi
    NSLog(@"str is %@", str);// str is lisiwangwu

}

#pragma mark Student对象的copy
void studentCopy(){

    Student *stu = [Student studentWithName:@"zhangsan"];
    
    Student *stu2 = [stu copy];
    
    stu2.name = @"lisi";
    
    NSLog(@"stu name is %@", stu.name);// stu name is zhangsan
    
    [stu2 release];

}


#pragma mark Student子类对象的copy
void goodStudentCopy(){

    GoodStudent *goodStu = [GoodStudent goodStudentWithAge:24 name:@"zhangsan"];
    
    GoodStudent *goodStu2 = [goodStu copy];
    
    goodStu2.name = @"lisi";
    goodStu2.age = 34;
    
    NSLog(@"goodStu name is %@", goodStu.name);// goodStu name is zhangsan
    NSLog(@"goodStu age is %i", goodStu.age);// goodStu age is 24

    [goodStu2 release];
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
//        studentNameCopy();
        studentCopy();
//        goodStudentCopy();
        
    }
    return 0;
}


     
     
    
    
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值