如何在objective-c中模拟受保护的属性和方法 [英] How to simulate protected properties and methods in objective-c

查看:114
本文介绍了如何在objective-c中模拟受保护的属性和方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

The way to declare private properties is simple.

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

You declare that in extension that's declared in .m files.

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

Say I want to declare protected properties and access it from the class and subclass.

这是我试过的:

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

#import "BGGoogleMap.h"

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

那个是编译.然后我补充说:

That one is compile. Then I added:

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap ()

-(NSString *) protectedHello
{
    return _
}

@end

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

Problem starts. I can't implement class extension outside the original .m files it seems. Xcode will demand something inside that bracket.

如果我这样做

#import "BGGoogleMap+protected.h"

@implementation BGGoogleMap (protected)

-(NSString *) protectedHello
{
    return _
}

@end

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

I cannot access the ivar of _protectedHello declared in BGGoogleMap+protected.h

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

Of course I can use regular category rather than extension, but that means I can't have protected properties.

那我该怎么办?

推荐答案

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

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

Class extensions are like anonymous categories, except that the methods they declare must be implemented in the main @implementation block for the corresponding class.

因此,您可以在类的主要 @implementation 中实现类扩展的方法.这是最简单的解决方案.

So you could just implement your class extension's methods in the class's main @implementation. That is the simplest solution.

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

A more complicated solution is to declare your "protected" messages and properties in a category, and declare any instance variables for that category in a class extension. Here's the category:

#import "BGGoogleMap.h"

@interface BGGoogleMap (protected)

@property (nonatomic) NSString * protectedHello;

@end

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

Since a category cannot add an instance variable to hold protectedHello, we need a class extension also:

#import "BGGoogleMap.h"

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

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

We need to include the class extension in the main @implementation file so that the compiler will emit the instance variable in the .o file:

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

@implementation BGGoogleMap

...

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

And we need to include the class extension in the category @implementation file so that the category methods can access the instance variables. Since we declared the protectedHello property in a category, the compiler will not synthesize the setter and getter method. We have to write them by hand:

#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 标头.

Subclasses should import BGGoogleMap+protected.h to be able to use the protectedHello property. They should not import BGGoogleMap_protectedInstanceVariables.h because the instance variables should be treated as private to the base class. If you ship a static library without source code, and you want users of the library to be able to subclass BGGoogleMap, ship the BGGoogleMap.h and BGGoogleMap+protected.h headers, but don't ship the BGGoogleMap_protectedInstanceVariables.h header.

这篇关于如何在objective-c中模拟受保护的属性和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆