类的属性及其子类

时间:2010-11-24 07:09:28

标签: objective-c properties protected instance-variables

是否可以定义仅对其定义的类以及该类的子类可用的属性?

换句话说,有没有办法定义受保护的属性?

4 个答案:

答案 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