【问题标题】:How to manage object when override setter in ARC?在 ARC 中覆盖设置器时如何管理对象?
【发布时间】:2014-09-09 02:57:34
【问题描述】:

当我为 @property 覆盖 setter 时,我有疑问。

即:

如果我设置这样的属性:

@property (strong) NSString *name;

在 'MRC' 中,它会自动生成 getter 和 setter,假设 setter 会像这样实现:

- (void)setName:(NSString *)name
{
    [_name release]; // Release previous.
    _name = name;
    [_name retain];  // Remain object.
}

当我在“MRC”中覆盖 setter 时,我可以通过遵循上面代码中的“强”行为来管理对象,

但是当在“ARC”中时,setter 将实现什么或如何管理对象以使其行为像“强”,因为它在“ARC”中没有“保留和释放”?

感谢您的宝贵时间!

【问题讨论】:

  • 您应该阅读有关 ARC 的文档。它涵盖了此类信息。
  • 顺便说一句,您的 MRC 实施很糟糕。第一行必须是autorelease

标签: ios objective-c


【解决方案1】:

在 ARC 下,编译器会生成这个 setter:

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

但是由于_name被声明为__strong(因为属性是strong),赋值变成了对objc_storeStrong的调用:

- (void)setName:(NSString *)name {
    objc_storeStrong(&_name, name);
}

objc_storeStrong 函数负责保留和释放,并且比您的更安全:

id objc_storeStrong(id *object, id value) {
  value = [value retain];
  id oldValue = *object;
  *object = value;
  [oldValue release];
  return value;
}

(如果name == _name 并且它的保留计数在 setter 开始时为 1,请考虑在 setter 中会发生什么。objc_storeStrong 函数也经过精心编写,以避免多个线程尝试同时设置属性。)

【讨论】:

    【解决方案2】:

    ARC 并不真正要求您做任何特殊或额外的事情,除了显式桥接到 Core Foundation 指针(编译器可以自动修复)。它主要要求您不要自己编写内存管理代码(如保留/释放调用)。你真的不需要“学习 ARC”,你只需要学习 ARC 无法为你处理的内存问题,比如保留周期(坏)和 C 指针的管理(即核心基础类型——除非从Swift,在这种情况下 ARC 也可以处理它们)。 ARC 的重点是自动化软件开发的一部分,这非常乏味且容易出错。你担心的更少,而不是更多。打个比方,为了使用 Core Data,您实际上不需要了解任何关于 SQL 的知识……更精细的细节已为您抽象出来。

    您通过声明它来使属性变得强大,在 setter 中没有什么特别需要做的:

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

    当然,这是一个愚蠢的例子,因为无论如何,当您所做的只是默认行为时,没有理由覆盖 setter。但是你明白了……

    【讨论】:

    • 简而言之,它会为您编写内存管理代码。这是您需要了解的 90%。
    猜你喜欢
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多