簡體   English   中英

objective-c中的類擴展

[英]class extension in objective-c

我正在通過閱讀書本來學習object-c。 當我閱讀關於類擴展的章節時,本書給出了以下示例代碼:

// A class extension
@interface BNREmployee ()

@property (nonatomic) unsigned int officeAlarmCode;

@end

@implementation BNREmployee
...
@end

該書說,不是BNREmployee實例的BNREmployee不能再看到這個屬性 officeAlarmCode 它舉了一個例子:

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

此嘗試將導致編譯器錯誤,其中顯示“No visible @interface聲明實例方法officeAlarmCode”。

但是我很困惑。 我的意思是我覺得這本書的文字及其示例代碼是矛盾的。 本書說,不是BNREmployee實例的BNREmployee不能再看到屬性officeAlarmCode 但是,在上面的示例代碼,是不是mikey的實例BNREmployee 為什么它看不到officeAlarmCode事件它是BNREmployee一個實例?

===更新=====

我正在讀的本書就是本書。 第22章,第162頁。

我只想驗證這本書是以誤導的方式解釋的,我在這里尋找明確的解釋。 因為書上說“那不是的實例對象BNREmployee ,像我這樣的電子書閱讀器不再能看到物業officeAlarmCode”,我覺得這暗示,是實例對象BNREmployee可以看到物業officeAlarmCode 這就是為什么我很困惑,因為mikey是一個實例BNREmployee但它不能訪問officeAlarmCode。

Mikes是BNREmployee的一個實例。 但是該示例告訴您,屬性officeAlarmCode沒有公開,只能由BNREmployee對象在內部使用。

說“物體再也看不見”有點誤導。 即使在比喻意義上,物體也看不到任何東西。 讓我們說: 代碼放置在類的實現之外無法看到屬性。

根據Apple Docs1 。類擴展可以將自己的屬性和實例變量添加到類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和可分配officeAlarmCodeotherAlarmCode財產像下面

BNREmployee *bnrEmployee = [BNREmployee alloc] init];
_otherAlarmCode = bnrEmployee.officeAlarmCode;
BNREmployee *mikey = [[BNREmployee alloc] init];
unsigned int mikeysCode = mikey.officeAlarmCode;
  • 此代碼位於文件中。 該文件(和該類)不是BNREmployee.m。此代碼位於非BNREmployee對象中。 讓我們調用這個代碼存在的對象foo
  • mikey是一個BNREmployee對象。
  • 此代碼嘗試訪問BNREmployee對象的officeAlarmCode屬性。
  • 當foo想要使用BNREmployee對象(如mikey)時,它可以訪問的屬性只是BNREmployee.h中的屬性。
  • 由於BNREmployee.h中不存在officeAlarmCode,因此foo無法訪問mikey的officeAlarmCode屬性,因為該屬性不在界面中(BNREmployee.h文件)。
  • 由於mikey是BNREmployee對象,因此可以查看officeAlarmCode並使用它。
  • mikey的代碼在哪里可以使用officeAlarmCode? mikey的代碼在BNREmployee.m文件中。 因此,唯一可以使用officeAlarmCode的代碼是BNREmployee的實現。

考慮上下文,只要擴展接口在給定上下文中“可見”,任何其他類都可以訪問在擴展名或任何類別中聲明的屬性。

例如,以下實現文件包含兩個接口的實現: BaseObjectBaseObjectController 在其他類( BaseObjectController )的實現中,您可以通過getter和setter安全地使用“hidden”屬性,因為聲明接口是“可見的”。 如果將BaseObjectController的實現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

我從中得到的是,物業officeAlarmCode只是中可見BNREmployee.m文件,它不會從訪問main.m

要通過價值mikeysCode你必須創建一個返回的方法officeAlarmCode

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM