• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

在objective-c模拟受保护的属性和方法

用户头像
it1352
帮助1

问题说明

可能的重复:
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.

那我该怎么办?

正确答案

#1

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.

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhcffifg
系列文章
更多 icon
同类精品
更多 icon
继续加载