如何创建一个只能在库中看到的目标c方法,而不是在导出的标题中

时间:2012-11-06 19:56:09

标签: objective-c ios objective-c-category

我正在构建一个用于控制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中导出?

3 个答案:

答案 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方法中。 这编译好并且有效。