7

可能重复:
objective-c 中的受保护方法

声明私有属性的方法很简单。

您在 .m 文件中声明的扩展名中声明它。

假设我想声明受保护的属性并从类和子类访问它。

这是我尝试过的:

//
//  BGGoogleMap+protected.h
//
//

#import "BGGoogleMap.h"

@interface BGGoogleMap ()
@property (strong,nonatomic) NSString * protectedHello;
@end

那就是编译。然后我补充说:

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap ()

-(NSString *) protectedHello
{
    return _
}

@end

问题开始。我似乎无法在原始 .m 文件之外实现类扩展。Xcode 将要求该括号内的内容。

如果我做

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap (protected)

-(NSString *) protectedHello
{
    return _
}

@end

我无法访问在 BGGoogleMap+protected.h 中声明的 _protectedHello 的 ivar

当然,我可以使用常规类别而不是扩展名,但这意味着我不能拥有受保护的属性。

所以我该怎么做?

4

3 回答 3

7

Objective-C 编程语言是这样说的:

类扩展类似于匿名类别,只是它们声明的方法必须在@implementation相应类的主块中实现。

所以你可以在类的 main 中实现你的类扩展的方法@implementation。这是最简单的解决方案。

一个更复杂的解决方案是在一个类别中声明您的“受保护”消息和属性,并在类扩展中声明该类别的任何实例变量。这是类别:

BGGoogleMap+protected.h

#import "BGGoogleMap.h"

@interface BGGoogleMap (protected)

@property (nonatomic) NSString * protectedHello;

@end

由于类别不能添加实例变量来保存protectedHello,我们还需要一个类扩展:

`BGGoogleMap_protectedInstanceVariables.h'

#import "BGGoogleMap.h"

@interface BGGoogleMap () {
    NSString *_protectedHello;
}
@end

我们需要在主@implementation文件中包含类扩展名,以便编译器在.o文件中发出实例变量:

BGGoogleMap.m

#import "BGGoogleMap.h"
#import "BGGoogleMap_protectedInstanceVariables.h"

@implementation BGGoogleMap

...

我们需要在类别@implementation文件中包含类扩展,以便类别方法可以访问实例变量。由于我们protectedHello在类别中声明了属性,因此编译器不会合成 setter 和 getter 方法。我们必须手写它们:

BGGoogleMap+protected.m

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap (protected)

- (void)setProtectedHello:(NSString *)newValue {
    _protectedHello = newValue; // assuming ARC
}

- (NSString *)protectedHello {
    return _protectedHello;
}

@end

子类应该导入BGGoogleMap+protected.h才能使用该protectedHello属性。它们不应该导入BGGoogleMap_protectedInstanceVariables.h,因为实例变量应该被视为基类的私有变量。如果您发布了一个没有源代码的静态库,并且您希望该库的用户能够继承BGGoogleMap、发布BGGoogleMap.hBGGoogleMap+protected.h标头,但不要发布BGGoogleMap_protectedInstanceVariables.h标头。

于 2012-12-01T04:05:11.780 回答
2

我希望我可以告诉你,但你不能。有关更多信息,请参阅此问题:Objective-C 中的受保护方法

于 2012-11-30T08:41:32.433 回答
0

我不确定,你想做什么?OOPS 概念中的一些黑客或数据抽象破解?

扩展用于添加属性。您已成功添加私有财产,如

#import "BGGoogleMap.h"

@interface BGGoogleMap ()
@property (strong,nonatomic) NSString * protectedHello;
@end

你在这做什么?

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap ()

-(NSString *) protectedHello
{
    return _
}

@end

你已经扩展了一个类,现在你又要实现同一个类了!!!两次!!!并且类别仅带有 .h 文件。我猜你正在为自己创建一个 .m 文件,这是不可接受的。

私有属性不能在类外访问,只能从基类或子类访问。这就是错误所在。

I can't implement class extension outside the original .m files it seems. 

是的,这是 Objective-c 的抽象和数据隐藏!!!

于 2012-11-30T10:06:06.813 回答