Objective-C ARC只读属性和私有setter实现

26

在ARC之前,如果我想要将属性设置为只读但在类内部可写,我可以这样做:

// Public declaration
@interface SomeClass : NSObject
    @property (nonatomic, retain, readonly) NSString *myProperty;
@end

// private interface declaration
@interface SomeClass()
- (void)setMyProperty:(NSString *)newValue;
@end

@implementation SomeClass

- (void)setMyProperty:(NSString *)newValue
{ 
   if (myProperty != newValue) {
      [myProperty release];
      myProperty = [newValue retain];
   }
}
- (void)doSomethingPrivate
{
    [self setMyProperty:@"some value that only this class can set"];
}
@end

使用 ARC,如果我想重写 setMyProperty,您不能再使用 retain/release 关键字,那么这样是否足够和正确?

// interface declaration:
@property (nonatomic, strong, readonly) NSString *myProperty;

// Setter override
- (void)setMyProperty:(NSString *)newValue
{ 
   if (myProperty != newValue) {
      myProperty = newValue;
   }
}
2个回答

62

没错,那是足够的了,但你甚至不需要那么多。

你可以这样做

- (void)setMyProperty:(NSString *)newValue
{ 
      myProperty = newValue;
}

编译器会在这里做正确的事情。

但是,你甚至不需要那个。在你的类扩展中,你实际上可以重新指定@property声明。

@interface SomeClass : NSObject
@property (nonatomic, readonly, strong) NSString *myProperty;
@end

@interface SomeClass()
@property (nonatomic, readwrite, strong) NSString *myProperty;
@end

这样做,你只需要合成一下,就会得到一个为你合成的私有setter。


1
谢谢Joshua - 非常有用!自那时以来,我一直在思考最后一件事情。阅读关于属性的ARC更改此处,似乎默认情况下它们由@synthesize实现,使用strong而不是assign。在这种情况下,为了使公共API更清洁,是否最好只指定(nonatomic, readonly),因为公共接口的用户没有必要关心或需要知道内部属性是强引用?希望我在这里表达得清楚。 :) - Quintin Willison
它只对对象类型强制,为了使事情更加明确,我仍然喜欢使用strongweakassign - Joshua Weinberg
确实,强类型只适用于对象类型,但问题仍然存在,即您的公共API(即头文件)是否需要发布此详细信息。这就是我要查询的真正重点! - Quintin Willison
我更喜欢这样做,以使其更明确。 - Joshua Weinberg
我问了一个类似的问题,不确定是否有所帮助(我仍然对内部发生的事情感到模糊)。https://dev59.com/1Ggv5IYBdhLWcg3wTvHL - Wayne Uroda

6
您可以在接口扩展中将您的属性重新声明为 readwrite:
@interface SomeClass()
@property (nonatomic, strong, readwrite) NSString *myProperty;
@end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接