【问题标题】:How to simulate protected properties and methods in objective-c [duplicate]如何在objective-c中模拟受保护的属性和方法[重复]
【发布时间】:2012-11-18 05:52:02
【问题描述】:

可能重复:
Protected methods in 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

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

那我该怎么办?

【问题讨论】:

  • Rob 写了一个在其他问题上没有的很棒的答案。这个问题也是关于模拟而不是实际的受保护变量,这是不可能在objective-c中实现的

标签: objective-c xcode4.5 protected


【解决方案1】:

The Objective-C Programming Language 这么说:

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

所以你可以在类的主要@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 标头。

【讨论】:

  • Rob,我认为单独使用 BGGoogleMap+protected.h 会产生编译错误。你试过这个吗?此外,这里的答案似乎有效。 stackoverflow.com/questions/3725857/… 因为也使用了协议,所以很尴尬。
  • 不,那边的答案根本不涉及房产,难怪只得到2个赞成票。
  • 嗯。也许你是对的。我会检查的。
  • 我不确定你在问什么。如果您遇到编译错误,请复制错误消息并发布。
  • 我不确定我们是否可以在类别中声明@property,这是整个问题。但是,后来我意识到您可以通过在扩展中声明 iVar 来解决这个问题。
【解决方案2】:

我希望我可以告诉你,但你不能。有关更多信息,请参阅此问题:Protected methods in Objective-C

【讨论】:

  • 谢谢你指出了一个正确的答案。
【解决方案3】:

我不确定,你想做什么? 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 的抽象和数据隐藏!!!

【讨论】:

  • "私有属性不能在类外访问,只能从基类或子类访问。"不知道属性,但方法不是这样,这是他想要的......
  • 他正在使用属性...请检查以访问他试图通过制作 setter 和 getter 来覆盖它的属性。所以他的主要想法是错误的,这就是他的问题被关闭的原因。
猜你喜欢
  • 2012-06-18
  • 2015-11-05
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 2020-03-31
  • 2012-01-08
相关资源
最近更新 更多