1

iOSの外部アクセサリを制御するための静的ライブラリを構築しています。その一環として、コンパイルされたライブラリとともに配布されるパブリックヘッダーの最小限のセットを提示したいと思います。

パブリックにする必要のあるクラスがありますが、その上にいくつかのフレームワークプライベートメソッドを作成したいと思います。イニシャライザを含むプライベートメソッドを追加するために、パブリッククラスの1つのカテゴリを作成しました。これはプロジェクトテストでは正常に機能しますが、-[MyClass initMethodDefinedInCategory:]:認識されないセレクターがインスタンスエラーに送信されます。

カテゴリヘッダー:

#import "MyClass.h"

@interface MyClass (LibraryPrivateMethods)
- (id)initMethod:(NSData *)data;
- (int)someOtherMethod:(NSData *)data;
@end

クラスの使用

#import "MyOtherClass.h"
#import "MyClass.h"
#import "MyClass+LibraryPrivateMethods.h"

@implementation MyOtherClass

#pragma mark - Instance Methods
- (id)initWithData:(NSData *)data
{
    self = [super init];
    if(self)
    {

        MyClass *mc = [[MyClass alloc] initMethod:data]; // errors here
        _property = mc;
    }
    return self;
}

このAppleテクニカルノート-ObjCで提案されているように、リンカーフラグを追加してみました。また、このSO回答で提案されているようにフラグを追加してみました。-all_load

編集:私はXCodeビルドに追加するだけで、以下に示すビルドスクリプトを確認するのを忘れていることに気づきました。

set -ex

INSTALL_PATH=$WORKSPACE/artifacts
[ -z $INSTALL_PATH ] || INSTALL_PATH=$PWD/artifacts

rm -rf $INSTALL_PATH
mkdir -p $INSTALL_PATH

PROJ=$SRCROOT/MyLib.xcodeproj

xcodebuild -project $PROJ -sdk iphoneos INSTALL_ROOT=$INSTALL_PATH/device install
xcodebuild -project $PROJ -sdk iphonesimulator INSTALL_ROOT=$INSTALL_PATH/simulator install

lipo -create -output $INSTALL_PATH/libMyLib.a $INSTALL_PATH/device/libMyLib.a $INSTALL_PATH/simulator/libMyLib.a
mv $INSTALL_PATH/device/Headers $INSTALL_PATH
rm -rf $INSTALL_PATH/device $INSTALL_PATH/simulator

# create zip for distribution.
(cd $INSTALL_PATH; zip -r ../MyLib-release.zip libMyLib.a Headers ../documentation/LibraryDocs/html ../documentation/LibraryDocs/docset)

ビルドスクリプトに-ObjCフラグを追加するのはどこですか?

カテゴリに初期化メソッドを含めることができない理由はありますか?このアップルのドキュメントが言うようにそれは可能のようです

カテゴリメソッドは、適切なクラスで定義されたメソッドが実行できることをすべて実行できます。実行時には、違いはありません。カテゴリがクラスに追加するメソッドは、他のメソッドと同様に、クラスのすべてのサブクラスに継承されます。

次に、クラス拡張を使用してみましたが、メソッドをフレームワーククラスのみに表示する方法がわかりません。

@interface MyClass ()
- (id)initMethod;
@end

その後、ライブラリ内の別のクラスから呼び出すと[[MyClass alloc] initMethod]、「MyClassの表示されない@interfaceがセレクターのinitMethodを宣言します」というエラーが発生します。

フレームワーク内の他のクラスにのみアクセス可能で、MyClass.hにエクスポートされないオブジェクトのメソッドを作成するにはどうすればよいですか?

4

3 に答える 3

1

カテゴリ宣言を別の.hファイルに入れます。フレームワーク内の.mファイルがカテゴリメソッドにアクセスする必要がある場合は、このプライベート.hファイルをインポートします。この.hファイルを、クライアントで使用するために配布されるパブリック.hファイルのセットにパッケージ化しないでください。

ところで=クラス拡張を使用せず、名前付きカテゴリを使用してください。

于 2012-11-06T20:01:43.583 に答える
0

問題に割り当てられた時間内にこれを機能させることができませんでした。最終的にカテゴリを削除し、初期化コードをMyOtherClassinitWithDataメソッドに移動しました。これは正常にコンパイルされ、機能します。

于 2012-11-11T21:53:34.047 に答える
0

AppleTechノートの下部にあるノートを参照してください。

重要:64ビットおよびiPhone OSアプリケーションの場合、-ObjCがカテゴリのみを含みクラスを含まない静的ライブラリからオブジェクトファイルをロードできないようにするリンカーのバグがあります。回避策は、-all_loadまたは-force_loadフラグを使用することです。

カテゴリコードのみが含まれているためMyClass+LibraryPrivateMethods.m、メモに記載されているバグが表示されているようです。

プライベート実装をメインのMyClass.mに移動するか、-all_loadまたは-force_loadフラグを試してください。

于 2012-11-06T21:01:49.820 に答える