【问题标题】:Better way to declare properties as protected将属性声明为受保护的更好方法
【发布时间】:2014-01-24 22:48:16
【问题描述】:

关注this blog post,我看到了解决我面临的问题的方法。

和他一样,我的问题是我有一个类,该类具有必须在其子类中继承和访问的属性:

@interface A : NSObject
@property (nonatomic, readonly) NSUInteger prop;
@end

@implementation A
    // Don't need to synthesize nowadays
@end

@interface B : A
    // No new properties
@end

@implementation B

- (void)establishValueForProp
{
    _prop = 1; // PROBLEM !!!
}

@end

解决办法是这样的:

@interface A : NSObject {
    @protected
    NSUInteger _prop;
}
@property (nonatomic, readonly) NSUInteger prop;
@end

我想知道是否还有另一种方法可以将属性声明为受保护?

【问题讨论】:

    标签: objective-c inheritance properties ivar


    【解决方案1】:

    我通常这样做的方式是创建第二个标题,例如称为“ClassName_ForSubclasses.h”。在该头文件中,添加一个类扩展,其中包含您希望子类能够调用和覆盖的属性和方法。然后,子类可以导入该标题,而该类的其他用户看不到它。

    【讨论】:

      【解决方案2】:

      另一种常见的做法是创建一个单独的 .h 文件(例如 ASubclass.h)并添加如下内容:

      @interface A (Protected)
      
      @property (nonatomic, readonly) NSUInteger prop;
      
      @end
      

      子类然后可以导入这个 .h 并且可以访问这个方法。请注意,由于类别无法添加属性,因此您必须在 A 的私​​有 interface(类扩展)中重新定义此属性。然后,该类别将提供对该属性的公共访问。 Apple 对 UIGestureRecognizer.h 和 UIGestureRecognizerSubclass.h 采用了这种精确的方法(其中 UIGestureRecognizer.h 公开了更多方法,供子类覆盖)。

      受保护(或私有)方法的概念实际上并不存在,这只是在某种程度上实现类似功能的一种方式。

      就个人而言,我只是在该类的(仅).h 文件中创建一个类别,该类别公开了一个公共属性。通过这种方式,它与主要的公共接口分离,并且由于无论如何都可以访问私有属性,我认为这种方法已经足够了。

      【讨论】:

      • 请注意,与我的回答相反,这需要您单独重新定义(或以其他方式提供访问器方法)主类接口或类扩展中的属性。在子类头中使用类扩展而不是命名类别没有这个问题。
      • @AndrewMadsen:我以为只能有一个类扩展?还是每个 .h 一个类扩展?
      • @Scott,不,据我所知,一个类的类扩展的数量没有限制,而且它们不必每个.h 分开一个(毕竟,当您#import a .h 时,它实际上是与正在编译的文件内联插入的)。这对于单个类具有三个类扩展,编译和运行都很好:gist.github.com/armadsen/8618759
      猜你喜欢
      • 2020-03-31
      • 2015-12-29
      • 2011-10-11
      • 1970-01-01
      • 2017-11-27
      • 2016-02-19
      • 2011-03-23
      • 2011-03-11
      相关资源
      最近更新 更多