Objective-C:(私有/公共属性)为外部类调用设置只读属性,为自调用设置只读属性

Posted

技术标签:

【中文标题】Objective-C:(私有/公共属性)为外部类调用设置只读属性,为自调用设置只读属性【英文标题】:Objective-C : (private / public properties) making a property readonly for outside class calls and readwrite for self calls 【发布时间】:2011-01-29 15:07:19 【问题描述】:

您是否知道一种方法可以使外部调用的属性只读而内部调用的读写?

我以前读过类似的东西

在.h

@property(nonatomic, readonly) NSDate* theDate;

在.m中

@interface TheClassName()
@property(nonatomic, retain) NSDate* theDate;
@end

但这会在编译 .m 时引发警告“TheClassName 类延续中的属性 theDate 属性与类 TheClassName 属性不匹配”。

无论如何,它似乎工作(可以从课堂外读取但不能设置,可以从内部进行)但我应该错过一些东西以避免警告。 或者,如果您知道更好的方法...

【问题讨论】:

【参考方案1】:

在您的 .h 中:

@property(nonatomic, retain, readonly) NSDate* theDate;

在您的 .m 中:

@interface TheClassName()
@property(nonatomic, retain, readwrite) NSDate* theDate;
@end

【讨论】:

+1,可能还想删除readwrite,因为这是默认设置,nonatomic,直到真的需要? readwrite 明确表明您知道自己想要什么。有些人将“始终使用nonatomic”的口号从 ios 带到 Cocoa(我当然愿意);这可能是一个项目范围的政策。 还有;两个地方都必须提到retain 的原因是retainassign 的getter 的@synthesis 的代码生成在某些情况下可能不同。因此,retain 对属性 的只读视图的策略是类的 API/合同的一部分。 这太棒了。谢谢! 我刚做了这个,想确保它是正确的。现在我确定 :) 谢谢!【参考方案2】:

如果您要迁移到 ARC,此问题将基本消除。您可以在标题中声明一次,而不是两个属性声明。

@property(nonatomic, readonly) NSDate* theDate;

然后在类扩展中,简单地声明一个__strong实例变量。

@interface TheClassName()

    __strong NSDate* _theDate;

@end

并在实现中适当地合成它们

@implementation TheClassName
@synthesize theDate = _theDate;

现在你可以设置实例变量了。

_theDate = [NSDate date];

ARC 会神奇地将适当的保留/释放功能内联到您的代码中,以将其视为强/保留变量。这具有比旧样式(保留)属性以及 ARC 在编译时内联保留/释放代码更快的优势。

【讨论】:

在这种情况下,您也可以将 _ 从 iVar 名称中去掉,因为 self.theDate 会发出警告,因为没有合成 getter 并且 __strong 可以防止您担心不安全地直接错误地设置 iVar . 但是,如果我希望 setter 或 getter 执行其他任务,例如广播通知、健全性检查,该怎么办? 然后你声明属性,并编写你需要的任何 getter 或 setter 方法,__strong 声明将阻止你在 setter 中实现任何保留/释放逻辑。 你听不懂,我想说的是:如果你因此使用属性调用,你会有更高程度的清洁和抽象。【参考方案3】:

如果属性由变量支持,则默认情况下该变量是从类内部读写的。将属性设为只读,您的设计目标将得到满足。在类中,引用变量而不添加 self.

【讨论】:

-1:即使在引用自己的实例变量时,也有很多很好的理由使用访问器。 (内存管理就是其中之一。)Oliver 的问题是有效的。【参考方案4】:

在 .m 中,您不应该再次输入 @property。不过,我不确定这有什么影响。 您的意思是使用@synthesize 吗?

请注意,无论如何,theDate 将在类实现中被读/写,而不管对外界是只读的。

【讨论】:

他正在使用类扩展。这可以用于私有属性,只能在 self ***.com/questions/4464112/… 上调用 不清楚这是否是 Oliver 试图实现的目标,但如果是,那么这是一个很好的答案。 Vikingosegundo,你应该把它作为答案,Oliver 可以接受! 他在问,如何实现一个公共的只读属性,而另一个私有属性具有读写访问权限。我从来没有做过这样的事情。我刚刚向您解释过,他正在使用类扩展,但它没有回答问题。

以上是关于Objective-C:(私有/公共属性)为外部类调用设置只读属性,为自调用设置只读属性的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C - 私有与受保护与公共

为啥类成员是私有的而属性是公共的? [复制]

Objective-C:访问继承类中的私有属性

Python入门-6面向对象编程:06私有属性和私有方法(实现封装)-@property装饰器-get和set方法-总结

内部类

具有公共getter的抽象属性,可以在具体类中定义私有setter吗?