在头文件中声明私有变量与在类扩展中声明变量

时间:2015-09-17 12:45:27

标签: ios objective-c instance-variables

在头文件中声明@private ivar和在没有@private的类扩展中声明相同的ivar之间有什么区别?据我所知,这是一回事。

另外,你能在标题中声明一个私有财产吗?

3 个答案:

答案 0 :(得分:3)

这个概念是在头文件中仅声明那些公开的东西(方法,属性等)。声明实现文件的类扩展中的所有私有项。

这仅为类用户提供可供其使用的信息,并隐藏所有其他信息。它还使班级用户更容易看到他可用的功能。编写代码完全是为了开发人员的可读性和可理解性。

这样,开发人员可以自由更改头文件中未公开的任何内容,而不会进行任何外部可见的更改。

在Objective的最新版本中,这最终可以通过类扩展完全释放。

答案 1 :(得分:2)

  

在头文件中声明@private ivar和在没有@private的类扩展中声明相同的ivar之间有什么区别?

存在一些差异。简而言之,在头文件中声明的变量对子类和类类别是可见的。实现中声明的变量不是。

1)在类的主@interface块中声明的实例变量可用于外部类类别或扩展,即使这些变量被声明为@private。 E.g:

// YourClass.h
@interface YourClass : NSObject {
    @private
    int _yourPrivateIVar; 
}
@end

// MyExtension.m
@implementation YourClass(MyExtension)
- (void)reset { _yourPrivateIVar = 0; } // This is allowed.
@end

实现中声明的实例变量不适用于外部类类别。

2)基类及其子类不能在@interface中声明相同的ivar,即使两个ivar都是@private。例如,这是不允许的:

@interface Base : NSObject
{
    @private
    int _foo;
}
@end

@interface Subclass : Base
{
    @private
    int _foo; // Error: Duplicate member _foo
}
@end

如果两个ivars都在类扩展或实现块中声明,那么它不仅可以编译,而且可以按预期工作:两个类都有自己独立的_foo ivars,它们之间不会相互冲突。换句话说,这两个变量都是真正的私有和独立的:

@implementation Base {
    int _foo;
}
@end

@implementation Subclass {
    int _foo;
}
- (void)reset { _foo = 123; } // Does not affect base class's _foo
@end

注意:如果基类和子类声明了一个具有相同名称的“私有”属性或方法,它将在没有警告或错误的情况下进行编译,但它会在运行时失败,因为这两个类在不知不觉中会干扰彼此的私有数据。 / p>

答案 2 :(得分:-1)

私人财产不能在头文件中声明。在.m文件中对iVar进行decalring与在.h文件中声明Content相同