【问题标题】:When declare a property(retain) in objective c, what's the default implementation of set/get method在目标 c 中声明属性(保留)时,set/get 方法的默认实现是什么
【发布时间】:2011-02-18 11:25:46
【问题描述】:

我是目标 c 的新手。我已经阅读了关于苹果“内存管理规则”的内存管理文档。但是我仍然不太清楚如何管理属性的引用。

对于使用“retain”注释声明的属性,set/get 访问方法的默认实现是什么?

这是我的假设,请给一些cmets。谢谢。

@interface SubClass : NSObject {
NSString * _name;
}
... ...
@property (nonatomic, retain) NSString * name;
... ...
@end

-(NSString *) setName {
   return _name;
}

-(void) setName: (NSString *) pName{
    // the correct version of default set method for retain
    if( _name != pName ) {
        [_name release];
        _name = [pName retain];
    }

}

那么dealloc方法,这样可以吗?

- (void)dealloc {
    self.name = nil; // or [_name release], _name = nil;

}

【问题讨论】:

  • 作为旁注,您无需在向其发送release 消息之前检查变量是否不为零。在 Objective C 中,您发送给 nil 对象的任何消息都会被忽略。
  • 哦,通常的做法是将NSString 属性声明为copy 而不是retain,因为它有一个广泛使用的可变子类。如果有人将您的 NSString 属性设置为 NSMutableString 子类的实例,他们可以从您的下方更改您的数据。
  • 一篇关于objective-c属性语法的好文章。 useyourloaf.com/blog/2011/2/8/…

标签: iphone objective-c ios


【解决方案1】:

正如 Matteo Alessani 所说,您可以简单地综合属性以获得默认实现。

作为参考,这是生成的(我通过阅读Objective-C Declared Properties 并将信息拼凑在一起得到的):

- (NSString *)name {
    return _name;
}

- (void)setName:(NSString *)aName {
    if (_name != aName) {
        [_name release];
        _name = [aName retain];
    }
}

【讨论】:

  • 谢谢!这很清楚。您能否提供您提到的“供参考”链接。我没找到。
【解决方案2】:

你可以在你的实现文件中使用 synthesize:

@implementation SubClass

@synthesize name = _name;

@end

您会自动获得默认的 getter 和 setter。

【讨论】:

    【解决方案3】:

    正如 Matteo 所说,您可以自动合成访问器方法。

    但是说到实现细节:

    1. 是的,getter 方法可能看起来像(但请注意正确的名称):

      -(NSString *) name {
         return _name;
      }
      

      或者当你使用名称值和持有它的对象被释放时处理这种情况:

      -(NSString *) name {
         return [[_name retain] autorelease];
      }
      
    2. setter 方法:

      -(void) setName: (NSString *) pName{
          NSString *temp = [pName retain];
          [_name release];
          _name = temp;
      }
      
    3. 释放。您的实现是好的,但是由于调用属性可能会导致一些副作用,依赖于对象中的所有字段都是有效的(在 dealloc 方法中可能不是这样),直接释放 ivar 可能会更好。

    您的 setter 示例是错误的,因为您不需要处理 nil 大小写(实际上在您的代码中,您永远不能将 name 值设置为 nil),但是当属性设置为同一对象时,您需要处理这种情况。

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2011-04-14
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多