2017-01-27 12 views
1

ただクラスメソッドを1つのプロジェクトで表示し、他のプロジェクトで非表示にしますか?

は、私はXCodeのとiOS用のObjective-Cでのプロジェクト/フレームワークを作成していますし、私は他のプロジェクトにさらに特定のプロジェクトに見えると隠さするメソッドを追加したい、としましょう、私の好奇心を落ち着かせます。

私の考えが分からない場合は、 私は3つの異なるプロジェクト(A、B、Cなど)としてさらに分割されたXCodeプロジェクトを作成しています。実際の実装を開始すると、プロジェクトAのすべてのクラスメソッドがプロジェクトBに表示されますが、プロジェクトCには表示されません。

iOS Objective-C/Swiftにこれを実装する方法はありますか?

+0

私は両方の言語(Objective-c、Swift)でカスタムフレームワークを開発しました。これは、独自のメソッドに対して異なるスコープ(公開、プライベート、保護)を行うことができないという事実です。 –

+1

エクステンションを使用できると思います。ここのようなものhttp://stackoverflow.com/questions/19095716/hiding-properties-from-public-framework-headers-but-leaving-available-internall – Mindaugas

+1

はい、拡張機能が動作します。 –

答えて

1

コメントの1つにMindaugasが述べたように、この目的のためにクラス拡張を使用できます。

クラス拡張は、クラス自体の実装内で使用するための追加のプライベートメソッドまたはプロパティを使用してパブリックインターフェイスを拡張するためによく使用されます。

は、例えば の.hは

@interface Person : NSObject 
@property(nonatomic, copy) NSString *firstName; 
@property(nonatomic, copy) NSString *lastName; 

- (void)setDateOfBirth:(NSDate *)date; 
@end 

.Mは

@interface Person() 
@property(nonatomic, strong) NSDate *dateOfBirth; 

- (void)calculateMyAge; 
@end 

@implementation Person 
- (void)setDateOfBirth:(NSDate *)date 
{ 
    self.dateOfBirth = date; 
    //Some more code goes here 
} 

- (void)calculateMyAge 
{ 
    //Do something with self.dateOfBirth here 
} 

@end 

は、ここでは、 @property dateOfBirthのとインタフェース人にプライベートメソッドcalculateMyAgeを作り、 @implementationブロックの下でそれを実現していますが含まれています。

@interface Person() 

は、クラス拡張(または名前のないカテゴリまたは匿名カテゴリ)以外は何もありません。

ここで元の質問に戻って、それをあなたのフレームワークに公開し、外部のために公開したいと考えています。

Personクラスに完全な名前(姓と名が追加された)を返すようにしたいとしましょう。しかし、あなたはフレームワークの内部目的にしたい。

このために別のヘッダーファイルを作成することができます。あなたのPerson.mファイルに

#import "Person+InternalHeader.h" 

をインポートすることができますし、@implementationブロックの下であなたは方法のために身体を実装することができます方法

@interface Person() 
- (NSString *)fullName; 
@end 

のための宣言を持っています

Person+InternalHeader.h 

@implementation Person 
//other code 
- (NSString *)fullName 
{ 
    return [self.firstName stringByAppendingFormat:@" %@",self.lastName]; 
} 
@end 

いつでもPerson + InternalHeader.hを他のクラスにインポートしてfullNameメソッドを使用できます。

なぜ拡張子ではないのですか?

拡張機能を使用すると、プロパティを上書きしたり、既存の親クラスに新しいプロパティを追加したりすることができます。また、子クラスでは、拡張で定義されたメソッドのデフォルト動作を常にオーバーライドできます。カテゴリを使用すると、既存のオブジェクトにメソッドが追加されます。

たとえば、クラスPersonから継承するDoctorクラスがあるとします。

@interface Doctor : Person 

ここで、fullNameメソッドが "Dr."プリペンド。 Doctor.mファイルのfullName動作を上書きするだけで済みます。

@implementation Doctor 
- (NSString *)fullName 
{ 
    NSString *fullName = [super fullName]; 
    return [@"Dr. " stringByAppendingString:fullName]; 
} 
@end 
+0

完璧な答え。すべてを説明します。ありがとう。 –

1

私は言語(Objective-c、Swift)でカスタムフレームワークを開発しました。独自のメソッド"(public func a(){})"に対して異なるスコープ(public、private、protected)を設定することはできません。フレームワーク内でどのような特定のメソッドを与えても、すべて(A、B、C)のプロジェクトで使用するプロジェクトは同じです。

+0

私はいつも少し奇妙だと思った。私はいつも、可視性は*言語*の一部ではなく、環境であるべきだと考えました。そして、あなたは一つのヘッダーだけでなく、あなたが望む "ヘッダー"を生成できるはずです。私はDylanがそうしたことを思い出しているようです。そのため、内部コードのみのヘッダーとパブリックヘッダーを使用できます。 –

0

プロジェクトの意味に応じて、ヘッダーを選択してインポートして、メソッドの表示に影響を与えることができます。

プロジェクトAは、クラスのメソッドを実装するクラスを持っている場合:

@implementation Antelope 

+ (void)leap 
{ 
    // Jump into the air 
} 

@end 

次に、あなたは、独自のヘッダーにカテゴリにそのメソッドの宣言を置くことができます。

// Antelope+Leaping.h 

#import "Antelope.h" 

@interface Antelope (Leaping) 

+ (void)leap; 

@end 

そして、コンパイラは、その特定のヘッダをインポートするファイルにのみ[Antelope leap]を書き込むことを許可します。もちろん、プロジェクトAはこれを支配していません。それは、プロジェクトBとプロジェクトCまでです。

このメソッドは依然としてクラスのメンバーであり、コンパイラを回避することはできますが、宣言が存在しない場合はメソッドが「可視」になりません。

+0

私たちはプロジェクトAにAntelopeクラスを作成していますので、ここではプロジェクトベースのアプローチに固執しましたが、「アクセススコープを持つn個のプロジェクト(A、B、C..n)のフレームワークベースのメソッドスコープ」iそれは不可能だと思う。 –

関連する問題