3

私は現在、APIと開発者の間の対話を容易にするためにiOS用のObjectiveCフレームワークを作成しているところです。この一環として、開発者がユーザーに情報を表示するために使用できる読み取り専用オブジェクトのさまざまな配列を返します。ただし、ユーザーに表示されるオブジェクトはフレームワークからのみ取得され、開発者がフレームワークを使用してインスタンス化できないようにしたいと思います。

私の現在の実装では、APIからJSONを取得してそれ自体をインスタンス化するカスタムコンストラクター初期化子を使用しています。カスタムコンストラクタ初期化子にアクセスすることを私が知っている唯一の方法は、その定義をヘッダーファイルに入れることです。これにより、自分自身だけでなく、開発者もアクセスできるようになります。ユーザーがデフォルトのコンストラクター初期化子を使用しようとすると、不整合例外をスローできることは承知しています-(id)init;が、独自のJSON文字列を作成してカスタムコンストラクター初期化子を呼び出すことを阻止することはできません。

プライベートフレームワークを使用している開発者からの干渉からプライベートフレームワークを保護するための正しいアプローチを取っていますか?これらのオブジェクトのデータの有効性を確保するために、他にどのようにこれを回避できますか?

出典:Objective-Cで-initメソッドをプライベートにすることは可能ですか?

4

2 に答える 2

3

Objective-Cは、その動的ディスパッチシステムのために、その性質上、真にプライベートなメソッドを許可していません。ただし、質問が真のセキュリティに関するものではなく、単にフレームワークを誤った方法で使用することを困難にしていると仮定すると、いくつかの選択肢があります。

単純で一般的な解決策は、公開したくないメソッドの宣言を別のヘッダーファイルのカテゴリに配置することです。これらのメソッドの実装は、クラスのメイン実装ファイルに引き続き配置できます。したがって、次のようなヘッダーがあります。

// MyClass+Private.h
@interface MyClass (Private)
- (void)aPrivateMethod;
@end

次に、これらのプライベートメソッドにアクセスする必要がある独自のソースファイルで、MyClass+Private.hをインポートするだけです。

フレームワークの場合、各ヘッダーファイルをパブリックまたはプライベートに設定できます。プライベートヘッダーはフレームワークバンドルにコピーされないため、フレームワークのユーザーには表示されません。これを行うには、Xcodeで[ユーティリティ]ペイン(右側のスライドアウトペイン)を開き、問題のヘッダーを選択してから、[ターゲットメンバーシップ]の下の関連する行の2番目の列で[プライベート]を選択します。

于 2013-03-14T16:53:35.410 に答える
0

Andrew Madsenのソリューションに基づいて、私が使用することになったのは、オブジェクトごとに2つの異なるヘッダーファイルを用意することでした。1つはパブリックで、もう1つはプライベートでした。パブリックヘッダーには、開発者が読み取り専用プロパティにアクセスするために必要な情報のみが含まれています。次に、プライベートヘッダーはパブリックヘッダーをインポートし、SDK内で使用する必要のあるすべてのメソッド呼び出し(初期化子を含む)を含むカテゴリも含みます。次に、プライベートヘッダーを実装にインポートします。構造は次のようになります。

パブリックヘッダーMyObject.h

#import <Foundation/Foundation.h>

@interface MyObject : NSObject
    @property (nonatomic, retain, readonly) NSString *myValue;
@end

プライベートヘッダーMyObject+Private.h

#import "MyObject.h"
@interface MyObject (Private)
    +(MyObject*)MyObjectFromJSONString:(NSString*)JSONString;
    -(id)initWithJSON:JSONString:(NSString*)JSONString
@end

プライベート実装MyObject.m

#import "MyObject+Private.h"
@implementation MyObject

@synthesize myValue = _myValue; //_myValue allows local access to readonly variable

- (id)init {
    @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"-init is not a valid initializer for the class MyObject" userInfo:nil];
    return nil;
}


+(MyObject*)MyObjectFromJSONString:(NSString*)JSONString;
{
    return [[MyObject alloc]initWithJSON:JSONString];
}


-(id)initWithJSON:JSONString:(NSString*)JSONString
{
    self = [super init];
    if(self){
        //parse JSON
        _myValue = JSONString;
    }
    return self;
}
于 2013-03-14T20:02:19.620 に答える