22

定義されているクラスとそのクラスのサブクラスでのみ使用できるプロパティを定義することは可能ですか?

別の言い方をすれば、保護されたプロパティを定義する方法はありますか?

4

4 に答える 4

15

技術的にはありません。プロパティは実際には単なるメソッドであり、すべてのメソッドはパブリックです。Objective-Cでメソッドを「保護」する方法は、他の人にメソッドを知らせないことです。

実際には、そうです。プロパティはクラス拡張で定義できますが、それでも@synthesizeメインの実装ブロックで定義できます。

于 2010-11-24T07:16:56.740 に答える
10

これは、基本クラスとサブクラスの両方の実装ファイルに含めるクラス拡張(カテゴリではない)を使用することで可能になります。

クラス拡張はカテゴリと同様に定義されますが、カテゴリ名はありません。

@interface MyClass ()

クラス拡張では、プロパティを宣言できます。これにより、バッキングivarを合成できます(XCode> 4.4 ivarの自動合成もここで機能します)。

拡張クラスでは、プロパティをオーバーライド/リファインし(読み取り専用を読み取り/書き込みなどに変更)、実装ファイルに「表示」されるプロパティとメソッドを追加できます(ただし、プロパティとメソッドは実際にはプライベートではなく、まだセレクターによって呼び出されます)。

他の人はこれに別のヘッダーファイル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ファイルでは、コンパイラが保護されたクラス拡張子を含めるように、使用する#define前に使用します。#import

于 2014-02-06T15:51:51.217 に答える
0

このような構文は、サブクラスの実装で使用できます。

@interface SuperClass (Internal)

@property (retain, nonatomic) NSString *protectedString;

@end
于 2013-01-12T11:34:49.133 に答える
0

カテゴリを使用して目的を達成できます

@interface SuperClass (Protected)

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

@end

サブクラスでは、このカテゴリをファイル.mにインポートします。

于 2019-07-20T10:59:06.823 に答える