gpt4 book ai didi

objective-c - 如何在 objective-c 库中隐藏对象

转载 作者:太空狗 更新时间:2023-10-30 03:50:08 26 4
gpt4 key购买 nike

我正在尝试创建一个用 Objective-C 编写的静态库。我想对这个库的消费者隐藏所有的实现细节。在此示例中,“OneThing”对象使用库内部的其他功能,包括“SecretThing”,它可能被库内的许多事物使用(并且不能隐藏在 OneThing 内)。但是,我不希望库的用户看到 OneThing 使用 SecretThing,或者 SecretThing 甚至存在,即使他们在 .a 文件中四处寻找。

@interface OneThing
+ (void) do;
@end
@interface SecretThing
+ (void) undo;
@end
@implementation OneThing
+ (void) do
{
[SecretThing undo];
}
@end
@implementation SecretThing
+ (void) undo { }
@end

如果我们编译它,并检查符号表:

% cc -c onething.m
% nm onething.o | grep Thing
0000000000000000 t +[OneThing do]
00000000000002f8 s +[OneThing do].eh
0000000000000040 t +[SecretThing undo]
0000000000000320 s +[SecretThing undo].eh
0000000000000078 S _OBJC_CLASS_$_OneThing
0000000000000050 S _OBJC_CLASS_$_SecretThing
00000000000000a0 S _OBJC_METACLASS_$_OneThing
00000000000000c8 S _OBJC_METACLASS_$_SecretThing
0000000000000128 s l_OBJC_$_CLASS_METHODS_OneThing
00000000000001d8 s l_OBJC_$_CLASS_METHODS_SecretThing
0000000000000190 s l_OBJC_CLASS_RO_$_OneThing
0000000000000240 s l_OBJC_CLASS_RO_$_SecretThing
0000000000000148 s l_OBJC_METACLASS_RO_$_OneThing
00000000000001f8 s l_OBJC_METACLASS_RO_$_SecretThing
%

正如我们所料,我们看到 OneThing 和 SecretThing 同样暴露。现在最好能以某种方式解决 SecretThing 的内部到库的使用,并且只将 OneThing 暴露给外部世界。我想做的是这个(只选择一种方法来尝试和管理):

% ld -r onething.o -exported_symbol "+[OneThing do]" -o onlyonething.o

我希望这会将“+[OneThing do]”标记为类型“T”,(文本全局),然后它会在“ strip ”中存活下来。它不是。这让我很烦恼,因为我认为这在某个时间点有效,也许当我更新工具链时,我得到了一个新版本的 ld ("ld -v"==ld64-133.3),它的工作方式不同。

除了获取链接器的源代码并编写我自己的新标志来执行我想要的操作外,我没有其他想法。我希望我只是太蠢了,有一些我不明白的东西让这更容易。


在答案中有人建议这从根本上说是不可能的,因为您需要运行时可用的所有链接信息来进行方法分派(dispatch)。我相信这个实验证明这不是真的。

# Move OneThing and SecertThing into their own files, with their own .h
% cat c_api.m
#include "OneThing.h"

void one_thing_do()
{
[OneThing do];
}
% cc -c c_api.c
% cat main.m
int main(int argc, char**argv)
{
extern void one_thing_do();

one_thing_do();
}
% cc main.m c_api.o onething.o secretthing.o -framework Foundation
% ./a.out
% ( runs to completion, no errors )

现在我们尝试隐藏我们不想让世界看到的部分:

% ld -r c_api.o onething.o secretthing.o -o strip_c_api.o -exported_symbol "_one_thing_do"
% strip -x c_strip_c_api.o
% nm strip_c_api.o
0000000000000118 s EH_Frame1
0000000000000098 s EH_Frame1
00000000000000d8 s EH_Frame1
U __objc_empty_cache
U __objc_empty_vtable
U _objc_msgSend
0000000000000000 T _one_thing_do
0000000000000130 s func.eh
00000000000000f0 s func.eh
00000000000000b0 s func.eh
0000000000000020 t l001
0000000000000060 t l002
0000000000000170 s l003
0000000000000190 s l004
00000000000001d8 s l005
0000000000000220 s l006
0000000000000240 s l007
0000000000000288 s l008
00000000000002f0 s l009
0000000000000318 s l010
0000000000000340 s l011
0000000000000368 s l012
% clang main.m strip_c_api.o -framework Foundation
% ./a.out
% nm a.out
0000000100001280 S _NXArgc
0000000100001288 S _NXArgv
0000000100001298 S ___progname
0000000100000000 T __mh_execute_header
U __objc_empty_cache
U __objc_empty_vtable
0000000100001290 S _environ
U _exit
0000000100000db0 T _main
U _objc_msgSend
0000000100000de0 T _one_thing_do
0000000100001000 s _pvars
U dyld_stub_binder
0000000100000d70 T start

最佳答案

由于 Objective-C 运行时的动态工作方式,这是不可能的。运行时需要这些信息来实例化类并向其发送消息,因此在不破坏您的库的情况下确实没有办法隐藏这些信息。

关于objective-c - 如何在 objective-c 库中隐藏对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11676186/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com