仅类及其子类的属性

发布于 2024-10-03 18:26:06 字数 59 浏览 7 评论 0原文

是否可以定义仅适用于定义它们的类及其子类的属性?

换句话说,有没有办法定义受保护的属性?

Is it possible to define properties that are only available to the class they are defined in, and that class's subclasses?

Stated another way, is there a way to define protected properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最舍不得你 2024-10-10 18:26:06

从技术上来说,不。属性实际上只是方法,并且所有方法都是公共的。我们在 Objective-C 中“保护”方法的方式是不让其他人知道它们。

实际上,是的。您可以在类扩展中定义属性,并且仍然在主实现块中@synthesize它们。

Technically, no. Properties are really just methods, and all methods are public. The way we "protect" methods in Objective-C is by not letting other people know about them.

Practically, yes. You can define the properties in a class extension, and still @synthesize them in your main implementation block.

帅气称霸 2024-10-10 18:26:06

这可以通过使用包含在基类和子类的实现文件中的类扩展(而不是类别)来实现。

类扩展的定义与类别类似,但没有类别名称:

@interface MyClass ()

在类扩展中,您可以声明属性,这将能够合成支持的 ivars(XCode > 4.4 自动合成 ivars 也适用于此)。

在扩展类中,您可以覆盖/优化属性(将只读更改为读写等),并添加对实现文件“可见”的属性和方法(但请注意,属性和方法并不是真正私有的,可以仍然由选择器调用)。

其他人建议为此使用单独的头文件 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,以便编译器包含受保护的类扩展。

This is possible by using a class extension (not category) that you include in the implementation files of both the base class and subclasses.

A class extension is defined similar to a category, but without the category name:

@interface MyClass ()

In a class extension, you can declare properties, which will be able to synthesize the backing ivars (XCode > 4.4 automatic synthesis of the ivars also works here).

In the extension class, you can override/refine properties (change readonly to readwrite etc.), and add properties and methods that will be "visible" to the implementation files (but note that the properties and methods aren't really private and can still be called by selector).

Others have proposed using a seperate header file MyClass_protected.h for this, but this can also be done in the main header file using #ifdef like this:

Example:

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

When you call #import, it basically copy-pastes the .h file to where you are importing it.
If you have an #ifdef, it will only include the code inside if the #define with that name is set.

In your .h file, you don't set the define so any classes importing this .h wont see the protected class extention.
In the base class and subclass .m file, you use #define before using #import so that the compiler will include the protected class extension.

漆黑的白昼 2024-10-10 18:26:06

您可以在子类实现中使用此类语法。

@interface SuperClass (Internal)

@property (retain, nonatomic) NSString *protectedString;

@end

You could use such syntax in subclass implementation.

@interface SuperClass (Internal)

@property (retain, nonatomic) NSString *protectedString;

@end
守护在此方 2024-10-10 18:26:06

您可以使用类别来达到您的目的

@interface SuperClass (Protected)

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIView *topMenuView;
@property (nonatomic, strong) UIView *bottomMenuView;

@end

在子类中,您可以在文件 .m 中导入此类别

You can use a category to gain your purpose

@interface SuperClass (Protected)

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIView *topMenuView;
@property (nonatomic, strong) UIView *bottomMenuView;

@end

In Subclass, you import this category in the file .m

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文