objective-c - 关于保留和复制

标签 objective-c ios copy retain

我以为我已经理解了retaincopy之间的区别。但当我遇到下面的代码时,我又困惑了。这些是代码:

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

?谢谢。

最佳答案

首先,-retainCountuseless to you .

第二,一个误解是在复制属性实现的实现上。您不会像您期望的那样在这里获得副本。相反,您得到的结果是 [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!

由于它们是不可变的且纯粹的,因此这在语义上是合理的。这还意味着,如果类型区分不可变副本和可变副本,您将需要自己为可变类型实现副本访问器。否则,当您尝试改变 ivar 时,您的程序可能会崩溃,因为您持有一个不可变的实例。如果将其添加到 -viewDidLoad 的末尾,您应该会看到一个异常:[self.c appendString:@"uh-oh"];

More detail on implementing a mutable property here .

关于objective-c - 关于保留和复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8687270/

相关文章:

linux - shell 脚本 : Copy directory passed as variable to another directory also as variable passed by user

iphone - 以横向模式打开 View

ios - 如何在 Interface Builder (Xcode) 中添加自定义控件

ios - UICollectionViewController 中的 Flipped CollectionView 被 Navigation Controller 覆盖

ios - iOS 中的多个委托(delegate)

text - Carbon Emacs 不会粘贴 Microsoft Word 的复制内容

ios - AFNetworking 和 id reponseObject 不工作并且无法恢复内容

ios - 创建一个通用的 UViewController 初始化器

ios - UIWebView - 限制内容宽度

arrays - 在 Perl 中,如何制作数组的深层复制?