我正在构建一个用于控制iOS外部附件的静态库。作为其中的一部分,我想呈现一组与编译库一起分发的最小公共头文件。
我有一个需要公开的类,但我想在其上创建一些框架私有方法。我为其中一个公共类创建了一个类别来添加私有方法,包括初始化程序。这适用于项目测试,但生成 - [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;
}
我已尝试按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]
,我会得到一个'No visible @interface for MyClass声明选择器initMethod'错误。
如何在对象上创建一个方法只能访问框架中的其他类,而不是在MyClass.h中导出?
答案 0 :(得分:1)
将类别声明放在单独的.h文件中。在框架中的任何.m文件中导入此私有.h文件需要访问类别方法。请勿将此.h文件打包到为客户端使用而分发的公共.h文件集中。
BTW =不使用类扩展,使用命名类别。
答案 1 :(得分:0)
请参阅the Apple Tech note底部的注释:
重要说明:对于64位和iPhone OS应用程序,存在一个链接器错误,该错误阻止-ObjC从仅包含类别而不包含类的静态库加载对象文件。解决方法是使用-all_load或-force_load标志。
由于MyClass+LibraryPrivateMethods.m
仅包含类别代码,因此您可能会看到笔记中描述的错误。
将私有实现移至主MyClass.m或尝试-all_load
或-force_load
标记。
答案 2 :(得分:0)
无法在为问题分配的时间内使其工作。我最终删除了类别并将初始化代码移动到MyOtherClass initWithData方法中。 这编译好并且有效。