关于C#:@property问题

@property question

在我的实现中,我有如下的getter和setter。我想使用属性并合成getter和setter,但有几个问题。

1
2
3
4
5
6
7
8
9
10
- (NSString *)title {
return title;
}

- (void)setTitle:(NSString *)value {
if(title != value) {
    [title release];
    title = [value retain];
}
}

如果要将其转换为属性,我将使用哪些属性?我是不是在想:

  • 读写,这样getter和setter都存在
  • 保持它增加值字符串的保留值,这样对象就不会丢失它。

我说得对吗?

最后一件事。我有下面的方法…

1
2
3
4
5
6
7
- (void)setReleaseDate:(NSString *)value {
// YYYY-MM-DD HH:MM:SS +HHMM
if([releaseDate description] != value) {
    [releaseDate release];
    releaseDate = [[NSDate alloc] initWithString:value];
}
}

我是否认为我仍然必须包含该方法,因为它包含合成getter不包含的代码?

谢谢。


对于标题属性,可以在类接口中声明它,如下所示:

1
@property (nonatomic, retain) NSString* title;

与以下内容相同:

1
@property (readwrite, nonatomic) NSString* title;

读写是一种默认设置。大多数情况下,您都希望为属性设置定位器,因此,当您不使用时,您将使用非默认的Read Onter来指定此设置。

非原子部分基本上意味着访问器将更快,并且通常使用。你可以在这里找到更多关于这个的信息:"非原子"属性是什么意思?.

对于第二个问题,如果愿意,可以实现自己的访问器。如果您这样做,那么它将"覆盖"由Objective-C生成的访问器。请记住,您必须遵守命名约定。因此,在您的示例中,您定义的"setReleaseDate:"方法将用于属性"releaseDate"的setter方法,这是完全正确的!:)但是,您遇到的问题是要传递一个*nsstring**来设置日期,这意味着此方法不会重写在您合成属性时将使用的默认setter。您必须传递一个与您设置为单个参数的值类型相同的值,因此在这种情况下,您必须传递一个*nsdate**。

您还必须确保,如果您提供自己的访问器实现,它将执行接口中声明的操作。我想你的释放期财产应该被宣布为保留。


您关于使用readwriteretain的断言是正确的,因为它将创建语义上等同于您所发布内容的代码。

不能合成ReleaseDate属性设置器,因为您要将NSString转换为NSDate来存储它,这也避免了NSString属性的常见问题,为此您最好使用copy来避免NSMutableString的问题。

除此之外,您的代码很好,除了字符串比较之外,您可能希望将简单的指针检查!=替换为isEqualToString,请参见比较coco中的字符串。


使用NSString属性的copy语义是很常见的,尽管并不总是必需的,以避免在背后更改NSMutableString对象的问题。

否则,你似乎是在它上面。