Objective-c之NSCopying
copy的原理:
执行<NSCopying>协议,类中必须实现copyWithZone:方法响应的copy消息。
copy消息将发送copyWithZone:这个消息给你的类,它的参数是nil。
copyWithZone:返回一个不可改变的copy
- *MyPoint.h*/
- #import <Foundation/Foundation.h>
- @interface MyPoint : NSObject<NSCopying>//继承超类
- {
- int x;
- int y;
- };
- //set方法
- -(void) setMyPoint:(int)x andY:(int)y;
- //get方法
- -(int) getX;
- -(int) getY;
- @end
- /*MyPoint.m*/
- #import "MyPoint.h"
- @implementation MyPoint
- -(void) setMyPoint:(int)_x andY:(int)_y
- {
- //要对传进来的x和y进行判断
- if(_x<0)
- {
- x = 1;
- }
- if(_y<0)
- {
- y = 1;
- }
- x = _x;
- y = _y;
- }
- -(int) getX
- {
- return x;
- }
- -(int) getY
- {
- return y;
- }
- //copy
- /*
- zone参数处理不同的你alloc出来的内存区域,如果你写的应用程序alloc了大量的内存,并且你又想优化你的内存区域。
- 你可以给copywithzone传值,调用allocwithzone来alloc内存:这个方法可以在指定的区域alloc内存
- */
- -(id) copyWithZone:(NSZone *)zone //创建一个复制的接收器,储存zone
- {
- MyPoint *newPoint = [[MyPoint allocWithZone:zone]init];
- [newPoint setMyPoint:x andY:y];
- return newPoint;
- }
- /*
- NSZone 是苹果系统对内存分配和释放的优化方式。
- NSZone不是一个对象;它是一个C结构,用于纪录关于内存处理(管理)一系列对象的信息
- 在这里它处理了zone这个传进来的对象的信息
- */
- @end
- #import <Foundation/Foundation.h>
- #import "MyPoint.h"
- int main (int argc, const char * argv[])
- {
- MyPoint *point1 = [[MyPoint alloc]init];//创建myPoint对象,alloc是分配内存空间,init是初始化
- [point1 setMyPoint:2 andY:3];//调用对象point1的方法
- NSLog(@"x = %i",[point1 getX]);//[point1 getX]调用get方法
- NSLog(@"y = %i",[point1 getY]);
- MyPoint *point2 = [point1 copy];//实现复制构造
- [point2 setMyPoint:5 andY:5];
- NSLog(@"x = %i",[point2 getX]);
- NSLog(@"y = %i",[point2 getY]);
- [point1 release];// release 是释放分配的内存空间
- [point2 release];
- return 0;
- }
ios拷贝小议
1.copy vs mutableCopy
copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.
mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.

2.copy vc retain
retain,引用计数+1,内存地址赋值给左值.
copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.
举例:

NSString* a = [NSString stringWithFormat:@"%@",@"this is a"]; NSString* b = [a copy]; NSString* bb = [a retain]; NSString* cc = [a mutableCopy];//实际上cc应该是NSMutableString类型 NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]); //输出3,3,3,1

NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"]; NSString* b = [a copy];//不可变的b NSString* bb = [a retain];//实际类型是NSMutableString的bb NSString* cc = [a mutableCopy];//同上 NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]); //输出2,1,2,1
3.一些问题
通过上面2点,思考下面的问题
我们通常如果这样定义一个变量
@property(nonatomic,copy) NSMutableString* mString;
然后这样使用

@synthesize mString; NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"]; self.mString = a; [mString insertString:@"m-" atIndex:0];

能通过么?当然不能,赋值后的mString是NSString类型的,不可变.如果需要可以改变就需要自己定义属性函数.

-(void)setMString:(NSMutableString *)m { mString = [m mutableCopy]; } -(NSMutableString *)mString { return mString; }
(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)
4.NSCopying NSMutableCopying NSCopyObjective()
NSCopying就是复制一个对象
NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响
(其实上面着两个完全看你怎么写啦)
NSCopyObject(self,0,zone)就是简单的赋值=
(在涉及到ns对象的时候,NSCopyObject不建议使用)
注意看下面一个例子:

@interface ClassB : NSObject <NSCopying>{
NSString* stringB;
} @property(nonatomic,copy) NSString* stringB; @end

-(id)copyWithZone:(NSZone *)zone { ClassB *b = NSCopyObject(self, 0, zone); // 使用NSCopyObject时的正确赋值方法,因为没有涉及到原来的内存指针什么事 b->stringB = @"what"; // 看看被注释的这个错误方法,由于setter方法的特性,原来的stringB指向的内存的retainCount减一 // 而由于NSCopyObject的特性,两者又是指向同一个地址的,所以,原类中stirngB指向的地址已经释放了,之后你dealloc中在释放一次?!.就出错啦 // b.stringB = @"what"; return b; }
- ios拷贝小议
-
1.copy vs mutableCopy
copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.
mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.
2.copy vc retain
retain,引用计数+1,内存地址赋值给左值.
copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.
举例:
NSString* a = [NSString stringWithFormat:@"%@",@"this is a"]; NSString* b = [a copy]; NSString* bb = [a retain]; NSString* cc = [a mutableCopy];//实际上cc应该是NSMutableString类型 NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);//输出3,3,3,1 NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"]; NSString* b = [a copy];//不可变的b NSString* bb = [a retain];//实际类型是NSMutableString的bb NSString* cc = [a mutableCopy];//同上 NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);//输出2,1,2,1
3.一些问题通过上面2点,思考下面的问题
我们通常如果这样定义一个变量
@property(nonatomic,copy) NSMutableString* mString;然后这样使用
@synthesize mString;NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];self.mString = a;[mString insertString:@"m-" atIndex:0];
能通过么?当然不能,赋值后的mString是NSString类型的,不可变.如果需要可以改变就需要自己定义属性函数.-(void)setMString:(NSMutableString *)m{ mString = [m mutableCopy];}-(NSMutableString *)mString{ return mString;}(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)
4.NSCopying NSMutableCopying NSCopyObjective()
NSCopying就是复制一个对象
NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响
(其实上面着两个完全看你怎么写啦)
NSCopyObject(self,0,zone)就是简单的赋值=
(在涉及到ns对象的时候,NSCopyObject不建议使用)
注意看下面一个例子:
@interface ClassB : NSObject <NSCopying>{ NSString* stringB;}@property(nonatomic,copy) NSString* stringB;@end-(id)copyWithZone:(NSZone *)zone{ ClassB *b = NSCopyObject(self, 0, zone);// 使用NSCopyObject时的正确赋值方法,因为没有涉及到原来的内存指针什么事 b->stringB = @"what";// 看看被注释的这个错误方法,由于setter方法的特性,原来的stringB指向的内存的retainCount减一// 而由于NSCopyObject的特性,两者又是指向同一个地址的,所以,原类中stirngB指向的地址已经释放了,之后你dealloc中在释放一次?!.就出错啦// b.stringB = @"what"; return b;}
Objective-c之NSCopying的更多相关文章
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- iOS开发——新特性OC篇&Objective新特性
Objective新特性 Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时, ...
- iOS开发核心语言Objective C —— 全部知识点总结
本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基 ...
- Objective C中的ARC的修饰符的使用---- 学习笔记九
#import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...
- Objective-O Runtime 运行时初体验
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...
- Objective的字符串拼接 似乎没有Swift方便,但也可以制做一些较为方便的写法
NSString *str1 = @"字符串1"; NSString *str2 = @"字符串2"; //在同样条件下,Objective的字符串拼接 往往只 ...
- [转] 从 C 到 Objective C 入门1
转自: http://blog.liuhongwei.cn/iphone/objective-c/ 进军iPhone开发,最大的难点之一就是怪异的Objective C语法了.不过,了解之后才发现,原 ...
- Objective C运行时(runtime)
#import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...
- Objective C ARC 使用及原理
手把手教你ARC ,里面介绍了ARC的一些特性, 还有将非ARC工程转换成ARC工程的方法 ARC 苹果官方文档 下面用我自己的话介绍一下ARC,并将看文档过程中的疑问和答案写下来.下面有些是翻译,但 ...
- Objective -C学习笔记 之copy(复制)
//自定义类对象实现copy需要遵守copy协议(否则程序崩溃),实现必须实现的协议方法,里面的代码就决定了你的copy是深是浅 #import <Foundation/Foundation.h ...
随机推荐
- mysql中group_concat函数用法
该函数返回带有来自一个组的连接的非NULL值的字符串结果.该函数是一个增强的Sybase SQL Anywhere支持的基本LIST()函数. 语法结构: GROUP_CONCAT([DISTINCT ...
- 通知模式实现两个textField传值及模态视图——iOS开发
通知模式实现两个textField传值及模态视图--iOS开发 利用通知模式,实现两个不同界面的textField之间的传值,在界面二输入字符,传值到前一界面的textField. 界面的切换,这里临 ...
- timestamp ---自动更新修改时间 与 记录首次插入时间
自动更新修改时间: mysql> create table z(a int ,b timestamp on update current_timestamp); mysql> insert ...
- Java实现常见排序算法
常见的排序算法有冒泡排序.选择排序.插入排序.堆排序.归并排序.快速排序.希尔排序.基数排序.计数排序,下面通过Java实现这些排序 1.冒泡排序 package com.buaa; import j ...
- linux下MySQL安装登录及操作
linux下MySQL安装登录及操作 二.安装Mysql 1.下载MySQL的安装文件 安装MySQL需要下面两个文件: MySQL-server-4.0.16-0.i386.rpm MySQL-cl ...
- 开始android博客分享
现在开始写博客,分享android开发中的心得.
- js获取图片高度
js获取图片高度时经常会获取的图片高度为0,原因是图片未加载完毕.第一次加载时,显示0(火狐等部分浏览器显示24).待加载完毕后,再刷新,显示图片高度258. var oImg = document. ...
- Java中JIN机制及System.loadLibrary() 的执行过程
Android平台Native开发与JNI机制详解 http://mysuperbaby.iteye.com/blog/915425 个人认为下面这篇转载的文章写的很清晰很不错. 注意Android平 ...
- 点击文字可以选中相应的checkbox
<html><head><title>中国站长天空-网页特效-表单特效-点击文字选中的复选框</title><meta http-equiv=&q ...
- Intellij Idea 13 vmoptions (Mac版本)
-ea -server -Xms1g -Xmx1g -Xss16m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DoEscapeAnalysis -XX:+ ...
我要投稿