是否可以定义仅对其定义的类以及该类的子类可用的属性?
换句话说,有没有办法定义受保护的属性?
答案 0 :(得分:15)
从技术上讲,没有。属性实际上只是方法,所有方法都是公共的。我们在Objective-C中“保护”方法的方式是不让其他人知道它们。
实际上,是的。您可以在类扩展中定义属性,并在主实现块中仍然@synthesize
。
答案 1 :(得分:10)
通过使用包含在基类和子类的实现文件中的类扩展(非类别),可以实现这一点。
类扩展的定义类似于类别,但没有类别名称:
@interface MyClass ()
在类扩展中,您可以声明属性,这将能够合成支持ivars(XCode> 4.4自动合成ivars也可以在这里工作)。
在扩展类中,您可以覆盖/优化属性(将readonly更改为readwrite等),并添加对实现文件“可见”的属性和方法(但请注意,属性和方法不是真的私有,仍然可以被选择器调用。
其他人建议使用单独的头文件MyClass_protected.h,但这也可以使用#ifdef
在主头文件中完成,如下所示:
示例:
BaseClass.h
@interface BaseClass : NSObject
// foo is readonly for consumers of the class
@property (nonatomic, readonly) NSString *foo;
@end
#ifdef BaseClass_protected
// this is the class extension, where you define
// the "protected" properties and methods of the class
@interface BaseClass ()
// foo is now readwrite
@property (nonatomic, readwrite) NSString *foo;
// bar is visible to implementation of subclasses
@property (nonatomic, readwrite) int bar;
-(void)baz;
@end
#endif
BaseClass.m
// this will import BaseClass.h
// with BaseClass_protected defined,
// so it will also get the protected class extension
#define BaseClass_protected
#import "BaseClass.h"
@implementation BaseClass
-(void)baz {
self.foo = @"test";
self.bar = 123;
}
@end
ChildClass.h
// this will import BaseClass.h without the class extension
#import "BaseClass.h"
@interface ChildClass : BaseClass
-(void)test;
@end
ChildClass.m
// this will implicitly import BaseClass.h from ChildClass.h,
// with BaseClass_protected defined,
// so it will also get the protected class extension
#define BaseClass_protected
#import "ChildClass.h"
@implementation ChildClass
-(void)test {
self.foo = @"test";
self.bar = 123;
[self baz];
}
@end
当您致电#import
时,它基本上会将.h文件复制粘贴到您导入的位置。
如果您有#ifdef
,则只有在设置了具有该名称的#define
时才会包含代码。
在你的.h文件中,你没有设置define,所以导入这个.h的任何类都不会看到受保护的类扩展。
在基类和子类.m文件中,在使用#define
之前使用#import
,以便编译器包含受保护的类扩展。
答案 2 :(得分:0)
您可以在子类实现中使用此类语法。
@interface SuperClass (Internal)
@property (retain, nonatomic) NSString *protectedString;
@end
答案 3 :(得分:0)
您可以使用类别来达到目的
@interface SuperClass (Protected)
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIView *topMenuView;
@property (nonatomic, strong) UIView *bottomMenuView;
@end
在子类中,将此类别导入文件 .m