我有A
在它的.m
文件中有此声明的类:
@implementation A {
NSObject *trickyObject;
}
B
在.h
文件中有此声明的类:
@interface B : A
@end
是否有可能trickyObject
从类中声明的方法访问B
?
如果您拥有私有的属性或方法,但是想让子类可以访问它,则可以将声明放在category中。
因此请考虑A
:
// A.h
@import Foundation;
@interface A : NSObject
// no properties exposed
@end
和
// A.m
#import "A.h"
// private extension to synthesize this property
@interface A ()
@property (nonatomic) NSInteger hiddenValue;
@end
// the implementation might initialize this property
@implementation A
- (id)init {
self = [super init];
if (self) {
_hiddenValue = 42;
}
return self;
}
@end
然后考虑以下类别:
// A+Protected.h
@interface A (Protected)
@property (readonly, nonatomic) NSInteger hiddenValue;
@end
请注意,此扩展名不进行合成hiddenValue
(其中的私有扩展名是A
这样做的)。但这为进口的任何人提供了A+Protected.h
访问此属性的机制。现在,在此示例中,尽管hiddenValue
确实是readwrite
(如的私有扩展中所定义A
),但此类别仅公开getter。(readonly
如果希望它同时公开getter和setter,显然可以省略,但是我将其用于说明性目的。)
无论如何,B
现在可以执行以下操作:
// B.h
#import "A.h"
@interface B : A
- (void)experiment;
// but again, no properties exposed
@end
和
// B.m
#import "B.h"
#import "A+Protected.h"
@implementation B
// but with this category, B now has read access to this `hiddenValue`
- (void)experiment {
NSLog(@"%ld", (long)self.hiddenValue);
}
@end
现在A
不公开hiddenValue
,但是任何使用此A (Protected)
类别的代码(在本例中为B
)现在都可以访问此属性。
因此,现在您可以调用B
可能使用hiddenValue
from的方法A
,而不必在公共接口中公开它。
// ViewController.m
#import "ViewController.h"
#import "B.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
B *b = [[B alloc] init];
[b experiment]; // this calls `B`’s exposed method, and that method is using the property not exposed by `A.h`
}
@end
如果您对真实示例感兴趣,请考虑UIKit:
@import UIKit.UIGestureRecognizerSubclass;
通常state
,a的ofUIGestureRecognizer
是readonly
,但是此UIGestureRecognizer (UIGestureRecognizerProtected)
类别公开了readwrite
访问器state
(顾名思义,仅用于手势识别器子类)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句