【问题标题】:Objective c - Reference counting目标 c - 引用计数
【发布时间】:2012-05-28 22:02:33
【问题描述】:

直到五分钟,我才确定自己对 Objective c 引用计数的理解非常好,但是当我开始检查对象的 retainCount 时,我对所看到的感到非常惊讶。

例如 myViewController 有一个 UITableview:

.h 文件

@interface RegularChatViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
     UITableView *_tableView;
}
@property (nonatomic, retain) IBOutlet UITableView *tableView; 

.m 文件

@synthesize tableView = _tableView;

- (void)loadView
{
    _tableView = [[UITableView alloc] init];  // STEP ONE
    NSLog(@"tableView retain count: %d",[_tableView retainCount]);

    self.tableView.frame = CGRectMake(0, 0, 320, tableHeight); // STEP TWO
    NSLog(@"tableView retain count: %d",[_tableView retainCount]);  

    [self.view addSubview:self.tableView]; // STEP THREE
    NSLog(@"tableView retain count: %d",[_tableView retainCount]); 
}

令我惊讶的是,输入是:

tableView retain count: 1
tableView retain count: 2
tableView retain count: 3

显然 STEP ONE 使用 alloc 将保留计数增加 1

我也知道第三步使用addSubview 将保留计数增加 1

但是第二步发生了什么???为什么它增加了保留计数???
和ARC有关系吗??

【问题讨论】:

  • 可能是因为.frame没有table view就无法存在,因此增加了retain count?
  • 猜对了;但是frame 直接返回一个结构;甚至没有参考。那里没有依赖关系。

标签: iphone objective-c ios reference-counting retaincount


【解决方案1】:

在第二步:- 通过使用自我。 tableView,tableview 属性的getter(设置为retain)将被调用。 因此,当您的财产被分配和保留时,保留计数分别增加。

当你必须分配一个保留属性时,你应该覆盖它的getter方法,这称为惰性实例化。

更好地在它的 getter 中分配你的 tableview,例如

-(UITableView *) tableView
{
     if(!_tableView) {
          _tableView  =  [[UITableView alloc]init];
     }

    return _tableView;
}

【讨论】:

    【解决方案2】:

    当从 getter 返回 tableView 时,self.tableView.frameretainautorelease

    【讨论】:

      【解决方案3】:

      我有一个方便的指南:When to use retainCount?

      简而言之,retainCount 很少会像您认为的那样。在不知道UITableViewUIView 是如何实现的情况下,您无法知道保留计数应该是多少。而且我们甚至没有考虑自动释放...

      【讨论】:

      • 这真的不是一个有用的网页,我讨厌看到它张贴在这里。一个没有解释的词只会给链接海报带来欢乐;这对提问者没有一点帮助。
      • 您向下滚动了吗?另请注意,我在答案中包含了所有相关信息。
      • 答案很好,当然。我从来没有在页面上向下滚动,没有。有了底部的链接,它比我想象的要好得多,但我不能是唯一一个看到那里没有其他东西的人,因为你似乎已经设置了它,因此对于大多数屏幕都没有底部内容的最初显示。
      【解决方案4】:

      一旦你与​​任何框架方法或函数进行交互,retainCount 方法就变得完全没用了,因为你不知道这些东西在它们的黑盒子里做了什么(他们可以添加你的对象自动释放池或其他),你不应该关心它。

      使用retainCount 来调试内存管理问题总是一个坏主意。请参阅this answer 了解更多避免它的原因。

      【讨论】:

        【解决方案5】:

        根据NSObject Protocol Reference 上的retainCount 方法的Apple 文档:

        重要 这种方法在调试内存管理问题时通常没有任何价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存了任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。

        【讨论】:

        • 确实如此。当我看到开发人员在他们的代码中注销保留计数时,我真的很担心。只要您遵守所有权规则并每隔一段时间使用 Leaks 工具,您就是金子。
        猜你喜欢
        • 2021-03-09
        • 2013-04-22
        • 1970-01-01
        • 1970-01-01
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多