专题:XX1iOS Developer

回头聊聊@property、copy和深浅拷贝

2017-02-26  本文已影响102人  eb2d18a460fb

聊聊@property、copy和深浅拷贝

关于property的由来

property关键字为我们自动地生成 setter/getter 方法。

早前OC中成员变量中accessor方法(setter/getter)需要自己构建,大多数时候都是重复的代码。比如对象的成员声明要这么写:

*.h

@interface Obj : NSObject{
NSString *_name;
}

- (NSString *)name;
- (void)setName:(NSString *)name;

@end

*.m

@implementation Obj

- (NSString *)name
{
    return _name;
}

- (void)setName:(NSString *)name
{
    _name = name;
}

@end

使用的时候这样做:

Obj *o = [[Obj alloc] init];
[o setName:@"my name!"];

NSString *name = [o name];
NSLog(@"%@", name);

当然上面的代码仅用于展示,在使用这个写法的时候还是手动进行内存管理。
上面的情况在成员变量较多的时候非常麻烦,java IDE提供了相应的功能来为我们自动添加,但Xcode选择了另一条路,引入了@property@synthesize来拯救我们,由 @property 生成.h中的声明语句,由 @synthesize 生成.m中的实现语句,代码大概是这样:

.h

@interface Obj : NSObject

@property NSString *name;

@end

.m

@implementation Obj

@synthesize name;

@end

这样清爽多了,后来苹果的工程师觉得这样写感觉还是多余了,于是决定帮再简化一点,在Xcode4.5后,只要有 @property 即可:

.h

@interface Obj : NSObject

@property NSString *name;

@end

.m

@implementation Obj

@end

配合 . 点语法,使用的时候不再通过OC独有的消息机制的写法来表达:

Obj *o = [[Obj alloc] init];
o.name = @"my name!";
NSString *name = o.name;

了解@property (nonatomic, strong, readwrite)的意义

到这里,我们知道这 @property 实际上做了哪些事情了,下面我们再来谈谈我们更关心的参数问题,举一个完整的例子:

@property (nonatomic, strong, readwrite) NSObject *obj;

property 声明的时候需要说明三个参数:

copy / mutableCopy

深拷贝与浅拷贝

苹果对于深拷贝与浅拷贝的说明,一目了然
核心内容看下图便明了,

主要见图主要见图

在Foundation对象中,默认是浅拷贝。以数组为例,浅拷贝(Shallo copy)仅对数组进行拷贝,与原数组共用其中的 Item, 深拷贝(Deep copy)对 数组及其中的 Item 都进行完全的拷贝,就是我们正常理解的拷贝。

其它

NSString

NSString拥有自己的内存管理机制和优化,使用时一般这样声明。

@property (nonatomic, copy) NSString *str;

我现在记忆比较深刻的优化内容如下:

NSString *str1 = [[NSString alloc] init];
NSString *str2 = @"a string.";

//此时 str1 和 str2 被保存在两个不同的内存区域

str1 = str2;
//此时 str1 的地址与 str2 相同

assign/retain/copy的实现方式

// assign
-(void)setTestObject :(id)newValue{
    testObject= newValue;
}

// retain
-(void)setTestObject :(id)newValue{
    if (testObject!= newValue) {
        [testObject release];
        testObject= [newValue retain];
    }
}
// copy
-(void)setTestObject :(id)newValue{
    if (testObject != newValue) {
        [testObject release];
        testObject = [newValue copy];
    }
}

版权声明:本文为本人原创文章,未经作者允许不得转载。

上一篇 下一篇

猜你喜欢

热点阅读