objective-c中的类扩展

时间:2015-01-15 12:32:44

标签: ios objective-c

我正在通过阅读一本书来学习object-c。当我阅读关于类扩展的章节时,本书给出了以下示例代码:

// A class extension
@interface BNREmployee ()

@property (nonatomic) unsigned int officeAlarmCode;

@end

@implementation BNREmployee
...
@end

本书说BNREmployee实例的对象无法再看到此属性 officeAlarmCode。它就是一个例子:

BNREmployee *mikey = [[BNREmployee alloc] init];
unsigned int mikeysCode = mikey.officeAlarmCode;

此尝试将导致编译器错误,显示“No visible @interface声明实例方法officeAlarmCode”。

但我感到困惑。我的意思是我感受到这本书的文字&它的示例代码是矛盾的。本书说,不是BNREmployee实例的对象不能再看到属性officeAlarmCode。但是在上面的示例代码中,不是mikey BNREmployee的实例?为什么它无法看到officeAlarmCode事件它是BNREmployee的实例?

===更新=====

我正在阅读的书是this one。第22章,第162页。

我只想验证这本书是以误导的方式解释的。我在这里寻找清楚的解释。因为本书说" NOT BNREmployee实例的对象再也看不到属性officeAlarmCode",对于像我这样的图书阅读器,我觉得它提示对象是实例BNREmployee可以查看属性officeAlarmCode。这就是我困惑的原因,因为mikeyBNREmployee的一个实例,但它无法访问officeAlarmCode。

6 个答案:

答案 0 :(得分:2)

Mikes是BNREmployee的一个实例。但该示例告诉您,属性officeAlarmCode未公开,并且只能由内部的BNREmployee对象使用。

答案 1 :(得分:2)

说“对象再也看不见”有点误导。即使在比喻意义上,物体也看不到任何东西。让我们说:代码放置在类的实现之外,看不到属性。

答案 2 :(得分:2)

根据Apple Docs 1.类扩展可以将自己的属性和实例变量添加到类中 2.类扩展通常用于扩展公共接口,使用其他私有方法或属性,以便在类本身的实现中使用。

因此,如果在类扩展中声明属性,它将仅对实现文件可见。像

BNREmployee.m

中的

@interface BNREmployee ()

@property (nonatomic) unsigned int officeAlarmCode;

@end

@implementation BNREmployee

- (void) someMethod {
    //officeAlarmCode will be available inside implementation block to use
     _officeAlarmCode = 10;
}
@end

如果你想在其他类中使用officeAlarmCode,让我们说是OtherEmployee类,那么你需要在BNREmployee.h文件中创建具有readOnly或readWrite访问权限的officeAlarmCode属性。然后你可以像

一样使用它
BNREmployee.h

@property (nonatomic, readOnly) unsigned int officeAlarmCode; //readOnly you can just read not write 
OtherEmployee.m

中的

import "BNREmployee.h"
@interface OtherEmployee ()

@property (nonatomic) unsigned int otherAlarmCode;

@end

@implementation OtherEmployee

您可以创建BNREmployee的实例,并可以将officeAlarmCode值分配给otherAlarmCode属性,如下所示

BNREmployee *bnrEmployee = [BNREmployee alloc] init];
_otherAlarmCode = bnrEmployee.officeAlarmCode;

答案 3 :(得分:0)

考虑上下文,任何其他类都可以访问在扩展或任何类别中声明的属性,只要扩展接口是"可见"在给定的背景下。

例如,以下实现文件包含两个接口的实现:BaseObjectBaseObjectController。在其他类(BaseObjectController)的实现中,您可以安全地使用"隐藏"属性通过getter和setter,因为声明界面是"可见"。如果将BaseObjectController的实现移动到另一个无法查看扩展声明的文件 - 此代码将无法编译。

#import "BaseObject.h"
#import "BaseObjectController.h"

//  BaseObject    
@interface BaseObject()
@property (strong) NSString * idString;
@end

@implementation BaseObject
@end

//  BaseObjectController    
@implementation BaseObjectController
- (void) initBaseObject {
    BaseObject * bo = [BaseObject new];
    bo.idString = @"01234";
}
@end

答案 4 :(得分:0)

我从中获得的是,officeAlarmCode属性仅在BNREmployee.m文件中可见,无法从main.m访问。

要将值传递给mikeysCode,您必须创建一个返回officeAlarmCode的方法。

答案 5 :(得分:0)

BNREmployee *mikey = [[BNREmployee alloc] init];
unsigned int mikeysCode = mikey.officeAlarmCode;
  • 此代码位于文件中。该文件(和该类)不是BNREmployee.m。此代码位于非BNREmployee对象中。让我们调用存在此代码的对象 foo
  • mikey是BNREmployee对象。
  • 此代码尝试访问BNREmployee对象的officeAlarmCode属性。
  • 当foo想要使用BNREmployee对象(如mikey)时,它可以访问的属性只是BNREmployee.h中的属性。
  • 由于officeNlarmCode在BNREmployee.h中不存在,因此foo无法访问mikey的officeAlarmCode属性,因为此属性不在界面中(BNREmployee.h文件)。
  • 由于mikey是BNREmployee对象,因此可以查看officeAlarmCode并使用它。
  • mikey的代码在哪里可以使用officeAlarmCode? mikey的代码在BNREmployee.m文件中。因此,唯一可以使用officeAlarmCode的代码是BNREmployee的实现。