【发布时间】:2012-11-06 19:56:09
【问题描述】:
我正在构建一个用于控制 iOS 外部附件的静态库。作为其中的一部分,我想展示一组最小的公共头文件,以与编译的库一起分发。
我有一个需要公开的类,但我想在它上面创建一些框架私有方法。我为其中一个公共类创建了一个类别来添加私有方法,包括一个初始化程序。这适用于项目测试,但会生成 -[MyClass initMethodDefinedInCategory:]: unrecognized selector sent to instance 错误。
类别标题:
#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;
}
我已尝试按照this Apple tech note 中的建议添加-ObjC 链接器标志。我还尝试按照this SO answer 中的建议添加-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 标志添加到构建脚本?
你有什么理由不能在一个类别中有一个初始化方法吗?正如this Apple doc 所说,这似乎是可能的
类别方法可以做任何在类中定义的方法 适当的可以做。在运行时,没有区别。方法 添加到类的类别被所有类的继承 子类,就像其他方法一样。
然后我尝试使用类扩展,但我不确定如何使该方法仅对框架类可见。
@interface MyClass ()
- (id)initMethod;
@end
如果我随后从库中的另一个类调用 [[MyClass alloc] initMethod],我会收到“MyClass 的无可见 @interface 声明选择器 initMethod”错误。
如何使对象上的方法只能被框架中的其他类访问,而不是在 MyClass.h 中导出?
【问题讨论】:
-
这很奇怪——我以前也遇到过这个问题,添加
-ObjC链接器标志解决了我的问题。在创建静态库和链接最终可执行文件时,您是否尝试将-ObjC标志传递给两个链接器命令行? -
你的
initMethodDefinedInCategory:方法的实现在哪里?它与公共方法在同一个 .m 中,还是在单独的 .m 文件中? -
@Darren 实现在 MyClass+LibraryPrivateMethods.m 文件中。所以一个单独的文件到公共方法。
-
@AdamRosenfield 你可能正在做某事。我忘记了构建脚本。将其添加到问题中。我将在构建脚本中的哪里传递 -ObjC 标志?还是 XCode 会自动做这种事情?
-
@aj.esler:如果您使用
xcodebuild来构建静态库,那么您不会在命令行上传递任何内容——您可以在某处添加-ObjC标志项目设置。如果没有明确的设置,应该在某处有一个“附加命令行选项”字段(或类似的东西)。
标签: objective-c ios objective-c-category