为什么我在子类中看不到继承的实例变量?

时间:2015-05-28 18:36:04

标签: ios objective-c inheritance instance-variables

我已经在Matt Neuberg的iOS编程基础知识中读到实例变量受到保护,这意味着除了这个类的子类之外的其他类都看不到它们。

我有一个父类A,我定义了一个ivar列表。 (A.M)

@interface A ()

@end

@implementation A
{
     NSArray *list;
}

@end

B类扩展A(B.h)

#import "A.h"

@interface B:A

@end

(B.m)

@interface B ()

@end

@implementation B

list = 
...

@end

我想在子类B中使用ivar列表,​​但编译器没有看到在父类中声明的引用。我已经尝试过明确使用@protected,但这并不起作用。我不想在公共界面上公开ivar列表。它是一个内部结构,是所有子类的共同元素。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

默认情况下,在类的公共接口外部声明的实例变量(换句话说,@interface部分)是私有。您可以在声明中添加可见性修饰符,以更改一个或多个ivars的可见性,如下所示:

@implementation A
{
     NSNumber *_ivarWithDefaultVisibility;

@protected
     NSArray *_list;
     NSString *_anotherIvarWithProtectedVisibility;
}

(请注意,根据Apple的Cocoa编码指南,ivar名称应以下划线为前缀。)

答案 1 :(得分:0)

这不是在ObjC中实现受保护属性的常用方法。 (@protected@private在Cocoa中很少使用。)首先,使用属性,而不是ivar。它会使它更清洁。以这种方式声明:

A.H

@interface A : NSObject
// Public interface goes here
@end

A.M

// Declare the property in a class extension inside the implementation file.
// This is the idiomatic way to create a "private" property.
@interface A ()
@property (nonatomic, readwrite, strong) NSArray *list;
@end

A + protected.h

// Enumerated any methods that should be accessible to subclasses here.
// Properties are just a special way of defining methods.
// The word "Protected" is just a category name.

@interface A (Protected)
@property (nonatomic, readwrite, strong) NSArray *list;
@end

B.h

#import "A.h"   
@interface B : A
...
@end

B.m

#import "B.h"
#import "A+protected.h"

// ... now you can use self.list ...

这种方法允许您创建任何类型的“受保护”方法,而不仅仅是属性,也是用于创建“朋友”类的技术。