copy--mutableCopy用法(important)

  1 //
  2 //  main.m
  3 //  cope-MultableCopy
  4 //
  5 //  Created by dingxiaowei on 13-5-19.
  6 //  Copyright (c) 2013年 dingxiaowei. All rights reserved.
  7 //
  8
  9 #import <Foundation/Foundation.h>
 10 #import "Student.h"
 11 #import "GoodStudent.h"
 12 //copy语法的目的:改变副本的时候,不会影响到原对像
 13
 14 //只有一种情况是浅拷贝,不可变对象调用copy方法,才是浅拷贝
 15
 16 #pragma mark - 演示字符串的mutableCopy语法(深拷贝)
 17 //深拷贝:是内容拷贝,会产生新对象,新对象计数器加1,原对象不变
 18 void stringmutableCopy(){
 19
 20     NSString *str=[[NSString alloc] initWithFormat:@"hello,%i。",10];
 21     NSLog(@"%@",str);
 22     //复制一个对象
 23     //产生一个新对象,计数器为1,原对象计数器不变
 24     NSMutableString *mustr=[str mutableCopy];
 25     NSLog(@"str:%zi",[str retainCount]);
 26     NSLog(@"mustr:%zi",[mustr retainCount]);
 27
 28     //判断是否是不同对象,str与mustr不是相同对象
 29     NSLog(@"%i",str==mustr);
 30
 31     //拼接一个字符串
 32     [mustr appendString:@"I am dingxiaowei"];
 33     NSLog(@"原来str%@",str);
 34     NSLog(@"现在mustr%@",mustr);
 35
 36     [mustr release];
 37     [str release];
 38 }
 39 #pragma mark - 演示字符串的Copy语法(浅拷贝)
 40 //浅拷贝:是地址拷贝,不会产生新对象,原对象计数器加1
 41 void stringCopy(){
 42     NSString *str=[[NSString alloc] initWithFormat:@"hi%i",10];
 43     NSLog(@"str:%zi",[str retainCount]);
 44     //copy产生的是不可变副本,由于原对像本来就不可变,所以为了性能着想,copy直接返回原对像本身
 45     NSString *newstr=[str copy];
 46     NSLog(@"str:%zi",[str retainCount]);  //由于是同一个对象,所以相当于str进行了一次retain操作
 47     NSLog(@"newstr:%zi",[newstr retainCount]);
 48     //返回值为1,说明还是返回的原来的对象,相当于return操作
 49     NSLog(@"是否相同:%i",str==newstr);
 50
 51     //执行两次release之后,才能完全释放该对象
 52     [str release];
 53     [newstr release];
 54     //NSLog(@"%zi",[str retainCount]);
 55 }
 56 #pragma mark - 可变字符串的copy(深拷贝)
 57 void mutableStringCopy(){
 58     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];
 59     //会产生一个新对象,计数器加1
 60     NSString *str=[string copy];
 61     //判断是否是同一个对象
 62     NSLog(@"%i",string==str);
 63
 64
 65     [str release];
 66 //    NSLog(@"%zi",[str retainCount]);
 67 }
 68 #pragma mark - 可变字符串的mutableCopy方法(深拷贝)
 69 void mutableStringmutableCopy(){
 70     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];
 71
 72     //产生一个新的对象,计数器加1
 73     NSMutableString *str=[string mutableCopy];
 74     [str appendString:@"  附加的字符串"];
 75     NSLog(@"%@",str);
 76     NSLog(@"%@",string);
 77     [str release];
 78 }
 79 #pragma mark - 演示Student的name的copy方法
 80 void studentNameCopy(){
 81     Student *stu=[[[Student alloc] init] autorelease];
 82     NSMutableString *string=[NSMutableString stringWithFormat:@"age is %i",10];
 83     stu.name=string;
 84     [string appendString:@"  append string"];
 85     //如果前面写的是Property(retain)NSString*name,那么这两句打印的结果就是一样的  都附加了string
 86     NSLog(@"name=%@",stu.name);
 87     //拷贝名字给副本对象
 88     Student *stucopy=[stu copy];
 89
 90     //打印两个对象
 91     NSLog(@"Stu1:%@",stu);
 92     NSLog(@"Stu2:%@",stucopy);
 93
 94     //因为内部实现的时候没有release,所以这里要必须释放对象
 95     [stucopy release];
 96
 97 }
 98 #pragma mark - 演示StudentCopy方法
 99 void studentCopy(){
100     Student *stu=[Student studentWithName:@"stu1"];
101     Student *stu2=[stu copy];
102
103     NSLog(@"stu1:%@",stu);
104     NSLog(@"修改前stu2:%@",stu2);
105     stu2.name=@"stu2";
106     NSLog(@"修改后stu2:%@",stu2);
107
108     [stu2 release];
109 }
110 #pragma mark - goodstudent的copy演示
111 void goodstudentCopy(){
112     GoodStudent *goodstudent=[GoodStudent goodstudentWithAge:20 Name:@"dingxiaowei"];  //这里要注意:调用的父类初始化方法,要在父类初始化方法里写一个【self class】alloc来创建一个初始化对象,返回一个子类的对象
113     NSLog(@"%@",goodstudent);
114     GoodStudent *newgoodstudent=[goodstudent copy];  //注意:这儿调用copy方法的时候,会取调用ocopywithzone方法,由于GoodStudent中没有实现,所以会取调用父类的这个方法,返回又会是父类对象,所以这里要注意修改父类方法里面那个方法的初始化对象,改成【self class】,或者对这个方法子类进行重写
115     NSLog(@"stu1:%@",goodstudent);
116     NSLog(@"修改前的stu2:%@",newgoodstudent);  //发现成功拷贝了
117
118     //修改stu2信息
119     newgoodstudent.name=@"cl";
120     newgoodstudent.age=22;
121     NSLog(@"修改后的stu2:%@",newgoodstudent);
122 }
123 int main(int argc, const char * argv[])
124 {
125
126     @autoreleasepool {
127
128 //        stringmutableCopy();
129 //        stringCopy();
130 //        mutableStringCopy();
131 //        mutableStringmutableCopy();
132 //        studentNameCopy();
133 //        studentCopy();
134         goodstudentCopy();
135     }
136     return 0;
137 }

Student.h

 1 #import <Foundation/Foundation.h>
 2
 3 @interface Student : NSObject<NSCopying>  //要实现NSCopying协议,才能调用类的copy方法
 4 //copy代表set方法会先release旧对象,然后copy新对象
 5 //用copy的话,修改外部的变量就不会印象到内部的成员变量
 6 //建议:一般NSString用copy,其他对象用retain策略
 7 //@property(nonatomic,copy)NSString *name;
 8 @property(nonatomic,retain)NSString *name;
 9
10 -(id)copyWithZone:(NSZone *)zone;
11
12 +(id)studentWithName:(NSString *)name;
13 @end

Student.m

 1 #import "Student.h"
 2
 3 @implementation Student
 4
 5 //-(void)setName:(NSString *)name{
 6 //    if(_name!=name){
 7 //        [_name release];
 8 //        //_name=[name retain]; //如果前面是Property(nonautomic,retain)所做的事情
 9 //        //如果前面是Property(nonautomic,copy)
10 //        _name=[name copy];
11 //    }
12 //}
13
14 +(id)studentWithName:(NSString *)name{
15     Student *stu=[[[[self class] alloc] init] autorelease]; //注意,这里[self class]取代Student 就是为了防止如果子类调用父类的方法,则返回的是父类的对象,会产生错误,所以这么操作就是返回子类的对象
16     stu.name=name;
17     return stu;
18 }
19 -(NSString *)description{
20     return [NSString stringWithFormat:@"[name=%@]",_name];
21 }
22
23 #pragma mark - copying方法
24 -(id)copyWithZone:(NSZone *)zone{
25     //注意:这里创建的copy对象,不要释放对象,因为我们在外面调用copy方法然后释放对象,在这里就不需要释放了
26     Student *copy=[[[self class] allocWithZone:zone] init];  //这里要特别注意:防止子类直接调用这个copywithzone方法而返回的是父类对象,要改成【self class】
27     copy.name=self.name;
28     return copy;
29 }
30
31 -(void)dealloc{
32     [_name release];
33     [super release];
34 }
35 @end

GoodStudent.h

 1 #import "Student.h"
 2
 3 @interface GoodStudent : Student
 4 //assign帮我们自动生成set和get方法
 5 @property(nonatomic,assign) int age;
 6
 7 //-(void)setAge:(int)age;
 8 //-(int)age;
 9
10 +(id)goodstudentWithAge:(int) age  Name:(NSString *)name;
11 @end

GoodStudent.m

 1 #import "GoodStudent.h"
 2
 3 @implementation GoodStudent
 4
 5 //-(void)setAge:(int)age{
 6 //    _age=age;
 7 //}
 8 //-(int)age{
 9 //    return _age;
10 //}
11
12 +(id)goodstudentWithAge:(int)age Name:(NSString *)name{
13     GoodStudent *goodstudent=[GoodStudent studentWithName:name];  //这个要注意可能返回的是父类对象,要在父类中修改
14     goodstudent.age=age;
15     return goodstudent;
16 }
17 //特别注意,description方法里面不能打印self本对象,不然会出现死循环
18 -(NSString *)description{
19     return [NSString stringWithFormat:@"goodStudent age is %i and name is %@",self.age,self.name];
20 }
21
22 //由于父类的copywithzone方法只实现了name的copy而没有实现子类特有属性的copy,所以要重写那个copywithzone方法
23 -(id)copyWithZone:(NSZone *)zone{
24     //首先要调用父类的这个方法
25     GoodStudent *copygoodstu=[super copyWithZone:zone];
26     copygoodstu.age=self.age;
27     return copygoodstu;
28 }
29
30 @end

时间: 2024-08-22 15:26:36

copy--mutableCopy用法(important)的相关文章

JAVA Zero Copy的相关知识

介绍      java 的zero copy多在网络应用程序中使用.Java的libaries在linux和unix中支持zero copy,关键的api是java.nio.channel.FileChannel的transferTo(),transferFrom()方法.我们可以用这两个方法来把bytes直接从调用它的channel传输到另一个writable byte channel,中间不会使data经过应用程序,以便提高数据转移的效率.     许多web应用都会向用户提供大量的静态内

iOS 热更新解读(二)—— JSPatch 源码解析

关于 JSPatch 的实现原理,JSPatch 作者本人 bang 已经有一系列文章阐述: JSPatch 实现原理详解 <一> 核心 JSPatch 实现原理详解 <二> 细节 JSPatch 实现原理详解 <三> 扩展 JSPatch 实现原理详解 <四> 新特性 JSPatch 实现原理详解 <五> 优化 这些文章是对 JSPatch 内部实现原理和细节诸如"require实现"."property实现&qu

iOS面试必看,最全梳理

原文 序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了.今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,加之,培训机构一火车地向用人单位输送iOS开发人员,打破了生态圈的动态平衡.矫情一下,言归正传,我奉献一下,为iOS应聘者梳理一下面试题,希望能助一臂之力! OC的理解与特性 OC作为一门面向对象的语言,自然具有面向对象的语言特性:封装.继承.多态.它既具有静态语言的特性(如C++),又有动态语言的效率(动态绑定.动态加载等).总体来讲,OC确实是一门不错的编程

iOS ARC 内存管理要点

前言 在讨论 ARC 之前,我们需要知道 Objective-C 采用的是引用计数式的内存管理方式,这一方式的特点是: 自己生成的对象自己持有.比如:NSObject * __strong object = [NSObject alloc] init];. 非自己生成的对象自己也能持有.比如:NSMutableArray * __strong array = [NSMutableArray array];. 自己持有的对象不再需要时释放. 非自己持有的对象自己无法释放. 而 ARC 则是帮助我们

介绍VB.NET的线程(英文)

One of the most notable new features in VB.NET is the ability to create threads in your application. Visual C++ developers have been able to write multithreaded code for years, but achieving the same effect in VB6 was fraught with difficulty. Althoug

autorelease探究

有时候我们需要延迟一个对象的引用计数减一操作,比如: + (NSArray *)array { return [[NSArray alloc] init] autorelease]; } 由于方法名并不以alloc, new, copy, mutableCopy开头,并且方法内部使用了alloc,需要对因此产生的引用计数负责. 不过如果直接调用release,将会返回野指针,所以我们需要autorelease机制来延迟释放. 我们需要先创建一个autorelease pool,才能有效地实现au

IOS有关内存管理的二三事

IOS有关内存管理的二三事 一.前引 随着移动设备的内存越来越大,程序员也已经度过了为了那一两M的内存在系统的抽丝剥茧的年代,对于JAVA的开发者,对内存更是伸手即取,并且从不关心什么时候还回去.但是,程序的掌控度对程序员来说是至关重要的,任何语言的内存管理机制的初衷也是在有限的空间里完成最精致的逻辑. 二.Xcode工程设置ARC ARC是xcode5中引入的自动引用计数,其原理与MRC是一样,只是系统帮助我们添加了retain和release.现在在xcode中新建的项目默认都是ARC的环境

Knockout应用开发指南 第七章:Mapping插件

原文:Knockout应用开发指南 第七章:Mapping插件 Mapping插件 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些属性是observable的,你可以使用KO绑定他们到你的UI元素上,当这些observable值改变的时候,这些UI元素就会自动更新. 绝大多数程序都需要从服务器端获取数据,但是由于服务器不知道observable的概念是什么,它只支持简单的JavaScript对象(通常是序列化以后的JSON),

iOS最新面试锦集

1. 为什么说Objective-C是一门动态的语言? ① 什么是动态语言? 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ruby.Python等也都属于动态语言,而C.C++等语言则不属于动态语言. 有三个名词容易混淆: Dynamic Programming Language (动态语言或动态编程语言) Dynamically Typed Langua

Objective-C之集合对象的内存管理

集合对象的内存管理 本小节知识点: [掌握]集合对象的内存管理 [理解]集合对象内存管理总结 1.集合对象的内存管理 当一个对象加入到集合中,那么该对象的引用计数会+1 当集合被销毁的时候,集合会向集合中的元素发送release消息 NSMutableArray *arr = [[NSMutableArray alloc] init]; Person *p = [[Person alloc] init]; NSLog(@"retainCount = %lu", [p retainCou