解决方法在Objective-C中完成受保护的属性

Ale*_*lom 39 properties protected objective-c

我一直在尝试找到一种解决方法来在Objective-C中声明@protected属性,因此只有层次结构中的子类才能访问它们(只读,而不是写入).我读到没有记录的方法这样做,所以我想到了这个解决方法,我想问一下StackOverflow对它的看法.

层次结构顶部的每个自定义类都包含三个类,一个实现和两个接口.我们给它们命名:

ClassA.h
ClassA_protected.h
ClassA.m
Run Code Online (Sandbox Code Playgroud)

那么这个ClassA的任何子类都会像往常一样:

ClassB.h
ClassB.m
Run Code Online (Sandbox Code Playgroud)

首先,我创建了接口ClassA.h,其中我声明了一个受保护的int变量,因此ClassA的任何子类都可以访问它:

@interface ClassA : NSObject{
    @protected
    int _myProtectedInt;
}
@end
Run Code Online (Sandbox Code Playgroud)

下一步是我正在谈论的解决方法.但是,一旦你阅读它,你会发现它非常直接.我声明了第二个名为ClassA_protected.h的接口,它实际上是ClassA.h 的扩展,允许我们将属性标记为readonly:

#import "ClassA.h"
@interface ClassA ()
@property (nonatomic , readonly) int myProtectedInt;
@end
Run Code Online (Sandbox Code Playgroud)

准备受保护层次结构的最后一步是在ClassA.m中声明它的实现,我们只合成我们的属性:

#import "ClassA_protected.h"
@implementation ClassA
@synthesize myProtectedInt = _ myProtectedInt;
@end
Run Code Online (Sandbox Code Playgroud)

这样,每个需要成为ClassA.h子类的类都将导入ClassA_protected.h.因此,像ClassB.h这样的孩子如下:

#import "ClassA_protected.h"
@interface ClassB : ClassA
@end
Run Code Online (Sandbox Code Playgroud)

以及从ClassB.m的实现中访问此属性的示例:

@implementation ClassB
-(void) method {
    //edit protected variable 
    _myProtectedInt= 1;

    //normal access
    self.muProtectedInt;
}
@end
Run Code Online (Sandbox Code Playgroud)

Ole*_*ann 20

当然,这很好.Apple在UIGestureRecognizer课堂上使用相同的方法.子类必须导入附加UIGestureRecognizerSubclass.h文件并覆盖该文件中声明的方法.


Sep*_*gus 7

对于简单的"属性",只需使用ivar.这与所有实用目的的属性一样好.

此外,默认值已受到保护.

  • 在某些情况下,属性是有益的.例如,KVO合规性,在一个地方设置/获取财产的能力(自定义设置器/获取器),脆弱的基类问题等. (3认同)