Сохранить и скопировать - PullRequest
       23

Сохранить и скопировать

2 голосов
/ 31 декабря 2011

Я думал, что понял разницу между retain и copy. Но когда я встретил код ниже, я снова запутался. Это код:

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    NSMutableString *a;
    NSMutableString *b;
    NSMutableString *c;
}

@property (nonatomic, copy) NSMutableString *a;
@property (nonatomic, copy) NSMutableString *b;
@property (nonatomic, copy) NSMutableString *c;

@end

ViewController.m:

#import "ViewController.h"

@implementation ViewController

@synthesize a, b, c;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.a = [[NSMutableString alloc] initWithFormat:@"%@", @"aaa"];
    NSLog(@"a:%d", a.retainCount);

    self.b = a;
    NSLog(@"a:%d", a.retainCount);
    NSLog(@"b:%d", b.retainCount);

    self.c = b;
    NSLog(@"a:%d", a.retainCount);
    NSLog(@"b:%d", b.retainCount);
    NSLog(@"b:%d", c.retainCount);
}

@end

Кто-нибудь может объяснить, почему результат:

2011-12-31 16:54:50.244 RetainCopy[5783:207] a:1
2011-12-31 16:54:50.246 RetainCopy[5783:207] a:2
2011-12-31 16:54:50.246 RetainCopy[5783:207] b:2
2011-12-31 16:54:50.247 RetainCopy[5783:207] a:3
2011-12-31 16:54:50.247 RetainCopy[5783:207] b:3
2011-12-31 16:54:50.248 RetainCopy[5783:207] b:3

? Спасибо.

1 Ответ

4 голосов
/ 31 декабря 2011

Во-первых, -retainCount для вас бесполезно .

Во-вторых, одно недоразумение заключается в реализации реализации свойства копии. Вы не получите копию здесь, как вы ожидаете. Вместо этого вы получаете результат [arg copy], а не [arg mutableCopy]. Многие неизменяемые типы «копируют» себя так (упрощенно):

- (id)copyWithZone:(NSZone*)zone
{
  return [self retain];
}

так что в конечном итоге результат будет:

NSMutableString * a = [[NSMutableString alloc] initWithString:@"aaa"];
NSString * b = [a copy]; // << returns an immutable copy!
NSString * c = [b copy]; // << immutable to immutable probably just retains itself!

Поскольку они неизменны и чисты, это семантически правильно. Это также означает, что вам потребуется самостоятельно реализовать средства доступа к копии для изменяемых типов, если тип различает неизменяемую и изменяемую копию . В противном случае ваша программа может взорваться, если вы попытаетесь изменить ивар, поскольку у вас есть неизменный экземпляр. Если вы добавите это в конец -viewDidLoad, вы должны увидеть исключение: [self.c appendString:@"uh-oh"];

Подробнее о реализации изменяемого свойства здесь .

...