2010-11-24 35 views

回答

15

從技術上講,沒有。屬性實際上只是方法,所有方法都是公共的。 Objective-C中「保護」方法的方式是不讓其他人知道它們。

實際上,是的。您可以在類擴展中定義屬性,並且仍然可以在主實現塊中使用這些屬性。

+1

要被「保護」,類擴展接口需要位於一個單獨的頭文件中,以包含在類及其子類中。 – JeremyP 2010-11-24 09:37:18

+0

據我所知,任何在基類接口擴展中聲明的屬性都不可用於子類 - 它們的作用域是私有的,不受保護。看到這個SO討論:http://stackoverflow.com/questions/5588799/objective-c-how-do-you-access-parent-properties-from-subclasses – memmons 2011-04-08 00:06:05

0

你可以在子類實現中使用這樣的語法。

@interface SuperClass (Internal) 

@property (retain, nonatomic) NSString *protectedString; 

@end 
9

這可以通過使用包含在基類和子類的實現文件中的類擴展(不是類別)來實現。

甲類擴展定義類似於類,但沒有類別名稱:

@interface MyClass() 

在一類擴展,可以聲明屬性,這將能夠合成所述背襯的ivars(的XCode> 4.4自動合成的ivars也適用於此)。

在擴展類中,您可以覆蓋/細化屬性(只讀更改爲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文件中,你不要設置定義,所以導入這個.h的任何類都不會看到受保護的類的擴展。 在基類和子類.m文件中,在使用#import之前使用#define,以便編譯器將包含受保護的類擴展。

相關問題