【问题标题】:Objective-C : (private / public properties) making a property readonly for outside class calls and readwrite for self callsObjective-C:(私有/公共属性)为外部类调用设置只读属性,为自调用设置只读属性
【发布时间】: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 属性不匹配”。

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

【问题讨论】:

    标签: objective-c cocoa


    【解决方案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 stackoverflow.com/questions/4464112/… 上调用
    • 不清楚这是否是 Oliver 试图实现的目标,但如果是,那么这是一个很好的答案。 Vikingosegundo,你应该把它作为答案,Oliver 可以接受!
    • 他在问,如何实现一个公共的只读属性,而另一个私有属性具有读写访问权限。我从来没有做过这样的事情。我刚刚向您解释过,他正在使用类扩展,但它没有回答问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 2015-06-09
    • 2014-04-12
    • 2013-02-26
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多