web-dev-qa-db-ja.com

Objective-Cプロジェクトで使用されるexternに関する3つの質問

  1. メソッドまたは変数の宣言の前にWordexternを使用する場合、それをグローバルにして、プロジェクト全体で読み取り/書き込み/使用可能にしますか?

  2. キーワードの前にexternを使用した場合、プロジェクトの一部でまだアクセスできない可能性はありますか?たとえば、「保護された」を使用する場合など、サブクラスによってのみ。

  3. externはCキーワードですよね? Objective-Cに同等のものはありますか?私は実際、Objective-CプロジェクトでCキーワードを使用する理由を理解していません。

ありがとう

24
aneuryzm

1)そのリンケージを指定しています。 externリンケージを使用すると、ユーザーまたは任意のクライアントがシンボルを参照できます。

グローバル変数に関して:変数が可変であるか、適切な構築が必要な場合は、このオブジェクトのメソッドまたは関数を検討する必要があります。これに対する注目すべき例外はNSString定数です。

// MONClass.h
extern NSString* const MONClassDidCompleteRenderNotification;
// MONClass.m
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification";

2)externキーワードが可視性(public/protected/private/package)に影響を与える場合はありません。シンボル(定数やC関数など)を使用するには、で宣言されているヘッダーを含めるだけです。

言語に不慣れな場合は多少混乱します。@interface ... @endの間にexternC宣言(定数、関数)を配置しても、スコープは変更されません。

@interface MONClass : NSObject

extern const size_t MaximumThreads;

@end

スコープ(グローバル)と可視性(パブリック)は次のものと同じです。

@interface MONClass : NSObject

@end

extern const size_t MaximumThreads;

したがって、クラス関連のC定数または関数を@interface...@endおよび@implementation...@endに配置することは実際には意味がありません。これらをインターフェースと同じヘッダーの@interface/@end@implementation/@endの外側に配置し、名前の前に関連付けられているクラスを付けることをお勧めします。

@interface MONClass : NSObject

@end

extern const size_t MONClassMaximumThreads;
// MONClass.m
const size_t MONClassMaximumThreads = 23;

その定数をプライベートにしたい場合は、次のように宣言して定義します。

// MONClass.m
static const size_t MONClassMaximumThreads = 23;

@implementation MONClass

@end

残念ながら、この定数をobjcで保護するための同様に簡単または一般的な方法はありません。

最後に、クラスごとに数を変える必要がある場合は、クラスメソッドを使用することもできます。

@interface MONMammal : NSObject
+ (NSUInteger)numberOfLegs;
@end

@implementation MONDog
+ (NSUInteger)numberOfLegs { return 4; }
@end
@implementation MONHuman
+ (NSUInteger)numberOfLegs { return 2; }
@end

3)はい、他の言語の中でも。たとえば、c ++変換でextern const int Somethingを使用する場合、c ++変換は外部C++シンボルとして宣言されたSomethingを検索します。 objcには置換はありません。 objcはCのスーパーセットであり、Cのすべての機能を継承します。 externの使用は整形式であり、使用するフレームワーク(Foundationなど)でも見つけることができます。リンケージを指定する必要があるため、これを使用します。 objcは、おそらく交換や拡張を必要としなかったため、代替品を提供していません。

これを回避するには、次のように#defineを使用します。

#if !defined(__cplusplus)
#define MONExternC extern
#else
#define MONExternC extern "C"
#endif

MONExternC const size_t MONClassMaximumThreads;
39
justin

externは「グローバル」を意味するのではなく、「他の場所で定義されている」ことを意味します。これは、変数または関数が(別のオブジェクトファイルまたはライブラリに)存在することをコンパイラに通知するために使用されます。これにより、コンパイラはそれについて文句を言わず、リンカにそのオブジェクトファイルまたはライブラリが提供されます。

結果として、externは、ターゲットアイテムがグローバルであることを意味します。

Objective-CはCの単なるスーパーセットです。Cで利用できるものはすべて、同じ構文とセマンティクスで、Objective-Cでも利用できます。 Objective-Cで別の方法で定義されているCの構成はありません。

17
mouviciel

ポイント3:はい、Objective CでFOUNDATION_EXPORTを使用できます。これは、CまたはC++のどちらをコンパイルするかに応じて異なるキーワードに解決されるマクロです。

違いについての詳細はこちら: "FOUNDATION_EXPORT" vs "extern"

0
Vlad