0
点赞
收藏
分享

微信扫一扫

Objective-c之NSCopying


​​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

[cpp] ​​view plain​​​​copy​​

/*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

[cpp] ​​view plain​​​​copy​​

#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,始终复制到新的内存中,以一个可变的类型赋值给左值.

Objective-c之NSCopying_深拷贝

2.copy vc retain

retain,引用计数+1,内存地址赋值给左值.

copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.

举例:

Objective-c之NSCopying_赋值_02

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

Objective-c之NSCopying_赋值_02

Objective-c之NSCopying_赋值_02

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

Objective-c之NSCopying_赋值_02

3.一些问题

通过上面2点,思考下面的问题

我们通常如果这样定义一个变量

@property(nonatomic,copy)  NSMutableString* mString;

然后这样使用

Objective-c之NSCopying_赋值_02

@synthesize mString;

NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];

self.mString = a;

[mString insertString:@"m-" atIndex:0];

Objective-c之NSCopying_赋值_02

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

Objective-c之NSCopying_赋值_02

-(void)setMString:(NSMutableString *)m

{

mString = [m mutableCopy];

}



-(NSMutableString *)mString

{

return mString;

}

Objective-c之NSCopying_赋值_02

(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)

4.NSCopying NSMutableCopying NSCopyObjective()

NSCopying就是复制一个对象

NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响

(其实上面着两个完全看你怎么写啦)

NSCopyObject(self,0,zone)就是简单的赋值=

(在涉及到ns对象的时候,NSCopyObject不建议使用)

注意看下面一个例子:

Objective-c之NSCopying_赋值_02

@interface ClassB : NSObject <NSCopying>{
NSString* stringB;
}

@property(nonatomic,copy) NSString* stringB;

@end

Objective-c之NSCopying_赋值_02

Objective-c之NSCopying_赋值_02

-(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_赋值_02

  1. 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;}


1.copy vs mutableCopy

copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.

mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.

Objective-c之NSCopying_深拷贝

2.copy vc retain

retain,引用计数+1,内存地址赋值给左值.

copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.

举例:

Objective-c之NSCopying_赋值_02

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

Objective-c之NSCopying_赋值_02

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

Objective-c之NSCopying_赋值_02


3.一些问题

通过上面2点,思考下面的问题

我们通常如果这样定义一个变量

@property(nonatomic,copy)  NSMutableString* mString;

然后这样使用

Objective-c之NSCopying_赋值_02

@synthesize mString;

NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];

self.mString = a;

[mString insertString:@"m-" atIndex:0];

Objective-c之NSCopying_赋值_02


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

Objective-c之NSCopying_赋值_02

-(void)setMString:(NSMutableString *)m

{

mString = [m mutableCopy];

}



-(NSMutableString *)mString

{

return mString;

}

Objective-c之NSCopying_赋值_02

(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)

4.NSCopying NSMutableCopying NSCopyObjective()

NSCopying就是复制一个对象

NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响

(其实上面着两个完全看你怎么写啦)

NSCopyObject(self,0,zone)就是简单的赋值=

(在涉及到ns对象的时候,NSCopyObject不建议使用)

注意看下面一个例子:

Objective-c之NSCopying_赋值_02

@interface ClassB : NSObject <NSCopying>{
NSString* stringB;
}

@property(nonatomic,copy) NSString* stringB;

@end

Objective-c之NSCopying_赋值_02

Objective-c之NSCopying_赋值_02

-(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_赋值_02


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;}



举报

相关推荐

0 条评论