黑马程序员---oc copy
来源:互联网 发布:莱恩打碟软件设置 编辑:程序博客网 时间:2024/06/06 03:54
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1.一般结结构体对象的copy和mutablecopy
只有一种情况是浅拷贝:不可变对象调用copy方法时
l一个对象使用copy或mutableCopy方法可以创建对象的副本
lcopy – 需要先实现NSCoppying协议,创建的是不可变副本(如NSString、NSArray、NSDictionary)
lmutableCopy – 需要先实现NSMutableCopying协议,创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
l深复制:内容拷贝,源对象和副本指向的是不同的两个对象。源对象引用计数器不变,副本计数器设置为1
l浅复制:指针拷贝,源对象和副本指向的是同一个对象。对象的引用计数器+1,其实相当于做了一次retain操作
l只有不可变对象创建不可变副本(copy)才是浅复制,其他都是深复制
2.一般自定义的对象的copy和mutablecopy(现在没感受到区别好像都是深拷贝)
对象的拷贝分为浅拷贝和深拷贝,浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址,深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性,即完全是两个东西,只不过内容相同而已。
拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:和相当于一个是拷贝,另一个是拷贝后可修改。
在最新版本的cocoa已经优化过了,所以有如下规则:
a:如果是Foundation框架里地不可变对象,就是Array,NSString等创建的对象,直接用copy来拷贝相当于retain,也就是属性还是同一个;
b:如果是用mutableCopy来拷贝,不管是可变还是不可变对象,属性神马的都直接拷贝了一份,即真正意义上得拷贝,它拷贝出来的对象统统都是可变的;
c:如果是可变对象,我们用copy也能实现真正意义上的拷贝,但是拷贝出来的对象是不可变的。
所以,我们拿name实验(因为age没有mutableCopy)实现语句的修改:
person.name=[_name mutableCopy]
person.age=[_age copy];
然后再输出person1和person2的name属性的地址,发现就不同了。
==========
自定义类的copy时,需要实现copyWithZone
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
Student *copy = [[[self class] allocWithZone:zone] init];
// 拷贝名字给副本对象 这样实现了深拷贝 // copy.name = self.name; copy.name=_name; //copy.name=[_name mutableCopy];//copy.name=[_name copy];return copy;
}
——————————————————————————————————
//// Student.h// copy-mutableCopy//// Created by amesty on 15-1-18.// Copyright (c) 2015年 itcast. All rights reserved.//#import <Foundation/Foundation.h>//因为这个类要支持拷贝,所以需要引入拷贝协议,有两种,后一种拷贝后可修改@interface Student : NSObject <NSCopying,NSMutableCopying>// copy代表set方法会release旧对象、copy新对象// 修改外面的变量,并不会影响到内部的成员变量// 建议:NSString一般用copy策略,其他对象一般用retain@property (nonatomic, copy) NSString *name;+ (id)studentWithName:(NSString *)name;@end
————————————————————————
#import "Student.h"@implementation Student+ (id)studentWithName:(NSString *)name { // 这里最好写[self class] Student *stu = [[[[self class] alloc] init] autorelease]; stu.name = name; return stu;}- (void)dealloc { [_name release]; [super dealloc];}#pragma mark description方法内部不能打印self,不然会造成死循环- (NSString *)description { return [NSString stringWithFormat:@"[name=%@]", _name];}#pragma mark copying协议的方法// 这里创建的副本对象不要求释放- (id)copyWithZone:(NSZone *)zone { Student *copy = [[[self class] allocWithZone:zone] init]; // 拷贝名字给副本对象 这样实现了深拷贝 //copy.name = self.name; copy.name=_name; //copy.name=[_name mutableCopy]; //copy.name=[_name copy]; return copy;}@end
————————————————————————
//// GoodStudent.h// copy-mutableCopy//// Created by amesty on 15-1-18.// Copyright (c) 2015年 itcast. All rights reserved.//#import "Student.h"@interface GoodStudent : Student@property (nonatomic, assign) int age;+ (id)goodStudentWithAge:(int)age name:(NSString *)name;@end
————————————————————————
#import "GoodStudent.h"@implementation GoodStudent+ (id)goodStudentWithAge:(int)age name:(NSString *)name { GoodStudent *good = [GoodStudent studentWithName:name]; good.age = age; return good;}- (NSString *)description { return [NSString stringWithFormat:@"[name=%@, age=%i]", self.name, _age];}- (id)copyWithZone:(NSZone *)zone { // 一定要调用父类的方法 GoodStudent *copy = [super copyWithZone:zone]; copy.age = [self.age copy]; return copy;}@end
————————————————————————
// 只有一种情况是浅拷贝:不可变对象调用copy方法时#import <Foundation/Foundation.h>#import "Student.h"#import "GoodStudent.h"// 只有一种情况是浅拷贝:不可变对象调用copy方法时// copy语法的目的:改变副本的时候,不会影响到源对象#pragma mark 演示字符串的拷贝(深拷贝)// 深拷贝:会产生新的对象,内容拷贝。新对象计数器置为1,源对象计数器不变。void stringMutableCopy() { // string:1 NSString *string = [[NSString alloc] initWithFormat:@"age is %i", 10]; // 产生了一个新的对象,计数器为1。源对象的计数器不变。 // str:1 // string:1 NSMutableString *str = [string mutableCopy]; //NSLog(@"str:%zi", [str retainCount]); //NSLog(@"string:%zi", [string retainCount]); // str和string不是相同对象 // NSLog(@"%i", str == string); [str appendString:@" abcd"]; NSLog(@"string:%@", string); NSLog(@"str:%@", str); // str:0 [str release]; // string:0 [string release];}#pragma mark 演示字符串的拷贝(浅拷贝)// 只有一种情况是浅拷贝:不可变对象调用copy方法时// 浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。void stringCopy() { NSString *string = [[NSString alloc] initWithFormat:@"age is %i", 10]; NSLog(@"%zi", [string retainCount]); // copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身 // 源对象计数器会+1 // 在浅拷贝情况下,copy其实就相当于retain NSString *str = [string copy]; NSLog(@"%zi", [string retainCount]); // NSLog(@"%i", str == string); [str release]; [string release];}#pragma mark 可变字符串的copy(深拷贝)void mutableStringCopy() { NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10]; // 会产生一个新对象,str计数器为1 NSString *str = [string copy]; [str release];}#pragma mark 可变字符串的MutableCopy(深拷贝)void mutableStringMutableCopy() { NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10]; // 会产生一个新对象,str计数器为1 NSMutableString *str = [string mutableCopy]; [str appendString:@"1234"]; NSLog(@"str:%@", str); NSLog(@"string:%@", string); [str release];}#pragma mark 演示Student的name的copyvoid studentNameCopy() { Student *stu = [[[Student alloc] init] autorelease]; NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10]; stu.name = string; [string appendString:@"abcd"]; NSLog(@"name=%@", stu.name); NSLog(@"string=%@", string);}#pragma mark 演示Student的copyvoid studentCopy() { Student *stu1 = [Student studentWithName:@"stu1"]; Student *stu2 = [stu1 copy]; stu2.name = @"stu2"; NSLog(@"stu1:%@", stu1); NSLog(@"stu2:%@", stu2); [stu2 release];}void goodStudentCopy() { GoodStudent *stu1 = [GoodStudent goodStudentWithAge:10 name:@"good1"]; GoodStudent *stu2 = [stu1 copy]; stu2.name = @"good2"; stu2.age = 11; NSLog(@"stu1:%@", stu1); NSLog(@"stu2:%@", stu2);}int main(int argc, const char * argv[]){ @autoreleasepool { studentCopy(); } return 0;}
- 黑马程序员---oc copy
- 黑马程序员——OC中的copy
- 黑马程序员-IOS-OC基础-浅析Copy语法
- 黑马程序员-OC笔记(十)copy-mutableCopy
- 黑马程序员---OC学习笔记之copy概念及入门
- 黑马程序员———OC语言 copy
- 黑马程序员--OC--OC简介
- 【转载】黑马程序员 OC基础-20 copy、mutablecopy以及自定义复制功能
- 黑马程序员---OC基础补充---补充:copy与mutableCopy、单例模式
- 黑马程序员——OC语言加强---copy概念及入门
- 黑马程序员——OC语言加强---@property中的copy关键字
- 黑马程序员---成长之路-----OC之基础篇Foundation©
- 黑马程序员 oc
- 黑马程序员-OC多态
- 黑马程序员--OC--分类
- 黑马程序员--oc:集合
- [黑马程序员][OC] 类
- [黑马程序员][OC]简介
- xcode6如何添加并配置pch文件
- 装饰设计模式、LineNumberReader
- 从字串的单词倒序算法到C#字串处理
- java基础-finally块对return变量的影响分析
- CodeBlocks暴力恢复默认设置
- 黑马程序员---oc copy
- excle计算两个日期相差天数
- Linux-权限管理-chattr与lsattr命令
- 脑洞大开的思维工具:PMI
- 整数的拆分1
- POJ2536 Gopher II【二分图最大匹配】
- WPF拖动总结
- 寻找最小的k个数
- 网狐的资料1