- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个使用 Apple 的 Safari 框架的 macOS 工具。在 macOS 10.13 中运行时,该工具会链接到并从中加载
/System/Library/PrivateFrameworks/Safari.framework
一切正常。但在 macOS 10.12.6 中运行时,某些行为会丢失。根据对 DTrace 的一些探测,我认为这是因为我的工具需要加载最新的 Staging 框架,如下所示:
/System/Library/StagedFrameworks/Safari/Safari.framework
这显然是 Safari 所做的,因为如果我使用 lldb 附加到 Safari 并运行image list
,则在 10.13 中该列表仅包含前一个路径,而在 10.12.6 中仅包含后者。
我尝试了以下方法:
NSBundle* stagedBundle = [NSBundle bundleWithPath:@"/System/Library/StagedFrameworks/Safari/Safari.framework"];
在 10.13 中返回 nil,因为此时没有这样的目录。但是,在 10.12.6 中,我得到了一个 stagedBundle,然后:
NSBundle* privateBundle = [NSBundle bundleForClass:[BookmarksController class]];
[privateBundle unload];
[stagedBundle load];
卸载和加载显然有效,因为如果我记录这两个包的 -description
,在运行该代码之前,私有(private)包是(已加载) 且 暂存 包是(尚未加载),但运行该代码后,这些状态会根据需要进行交换。
但是没有效果。 (1) 如果我再次调用 -bundleForClass:
,传递一个已知在两个框架中的类,它会为我提供 Private 包。 (2) 如果我调用 -respondsToSelector:
,传递已知仅存在于 Staging 框架中的选择器,我会得到“否”。
我尝试按照建议调用_CFBundleFlushBundleCaches()
here ,但这并没有帮助。
我还尝试更改目标的 FRAMEWORK_SEARCH_PATHS
,并在我的 Mac 上安装 Staging 框架并链接到它,但由于这篇文章已经太长了,我'我只能说这产生的热量多于光。
在这种情况下如何有选择地加载框架?
更新
我尝试了另一种方法。重新阅读苹果的Framework Programming Guide后,尽管看起来确实过时了,但我认为这个框架需要弱链接。这样做了:
-load
和 -unload
调用-weak_framework Safari
这对我来说很有意义,在 10.13 和 10.12.6 中构建并运行,但它显然仍在 10.12.6 中加载不需要的私有(private)框架。 NSLog 将其报告为 bundle 的路径,并且类不会响应仅位于 Staging 框架中的选择器。
还有其他想法吗?
最佳答案
首先,免责声明:我强烈建议您不要在交付给用户的任何应用程序中依赖加载私有(private)框架。它很脆弱并且没有支撑。
也就是说,如果您确实想这样做,我的建议是使用 Safari 本身在框架的两个副本之间进行选择的相同技术,即 dyld
的 DYLD_VERSIONED_FRAMEWORK_PATH
环境变量。
引用dyld
man page :
This is a colon separated list of directories that contain potential override frameworks. The dynamic linker searches these directories for frameworks. For each framework found dyld looks at its
LC_ID_DYLIB
and gets thecurrent_version
and install name. Dyld then looks for the framework at the install name path. Whichever has the largercurrent_version
value will be used in the process whenever a framework with that install name is required. This is similar toDYLD_FRAMEWORK_PATH
except instead of always overriding, it only overrides is the supplied framework is newer. Note: dyld does not check the framework's Info.plist to find its version. Dyld only checks the-current_version
number supplied when the framework was created.
简而言之,这会导致 dyld 在正在加载的框架和版本化框架路径中的框架之间执行版本检查,并加载更高版本。如果版本化框架路径不存在或者其中不存在相关框架,则将使用原始框架路径。
Safari 使用第二个 dyld
功能来简化其对 DYLD_VERSIONED_FRAMEWORK_PATH
(LC_DYLD_ENVIRONMENT
加载命令)的使用。此加载命令允许在链接时指定DYLD_*
环境变量,该变量将由dyld
在运行时尝试加载任何依赖库之前应用。如果没有这个技巧,您需要在启动应用程序之前将 DYLD_VERSIONED_FRAMEWORK_PATH 设置为环境变量,这通常需要繁琐的重新执行才能实现。
将这两个构建 block 放在一起,您最终会添加如下配置设置:
OTHER_LDFLAGS = -Wl,-dyld_env -Wl,DYLD_VERSIONED_FRAMEWORK_PATH=/System/Library/StagedFrameworks/Safari;
然后,您可以静态链接到 /S/L/PrivateFrameworks/Safari.framework
,或尝试在运行时动态加载它。两者都应该导致在运行时加载适当的框架。
为了解决您的问题所揭示的一些误解:
The unloading and loading apparently works, because if I log -description of those two bundles, before running that code the Private bundle is (loaded) and the Staged bundle is (not yet loaded), but after running that code those states are swapped, as desired.
不支持卸载包含 Objective-C 代码的共享库。我怀疑它所做的唯一事情是导致在NSBundle
实例上切换“已加载”标志,因为在dyld
的级别它被忽略。
In Build Settings > Framework Search Paths, listed paths to both frameworks' parent directories, with the Staged path before the Private path, because I want this one to load in macOS 10.12.6, where both exist.
框架搜索路径是一个仅在编译时使用的概念。在运行时,库的安装名称告诉dyld
在哪里可以找到要加载的二进制文件。
关于macOS:根据可用性在运行时加载一个或其他系统框架,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49375324/
我想要显示正在加载的 .gif,直到所有内容都已加载,包括嵌入的 iframe。但是,目前加载 gif 会在除 iframe 之外的所有内容都已加载后消失。我怎样才能让它等到 iframe 也加载完毕
首先,这是我第一次接触 Angular。 我想要实现的是,我有一个通知列表,我必须以某种方式限制 limitTo,因此元素被限制为三个,在我单击按钮后,其余的应该加载。 我不明白该怎么做: 设置“ V
我正在尝试在我的设备上运行这个非常简单的应用程序(使用 map API V2),并且出于某种原因尝试使用 MapView 时: 使用 java 文件: public class MainMap e
我正在使用 Python 2.6、Excel 2007 Professional 和最新版本的 PyXLL。在 PyXLL 中加载具有 import scipy 抛出异常,模块未加载。有没有人能够在
我想做这个: 创建并打包原始游戏。然后我想根据原始游戏中的蓝图创建具有新网格/声音/动画和蓝图的其他 PAK 文件。原始游戏不应该知道有关其他网格/动画/等的任何信息。因此,我需要在原始游戏中使用 A
**摘要:**在java项目中经常会使用到配置文件,这里就介绍几种加载配置文件的方法。 本文分享自华为云社区《【Java】读取/加载 properties配置文件的几种方法》,作者:Copy工程师。
在 Groovy 脚本中是否可以执行条件导入语句? if (test){ import this.package.class } else { import that.package.
我正在使用 NVidia 视觉分析器(来自 CUDA 5.0 beta 版本的基于 eclipse 的版本)和 Fermi 板,我不了解其中两个性能指标: 全局加载/存储效率表示实际内存事务数与请求事
有没有办法在通过 routeProvider 加载特定 View 时清除 Angular JS 存储的历史记录? ? 我正在使用 Angular 创建一个公共(public)安装,并且历史会积累很多,
使用 Xcode 4.2,在我的应用程序中, View 加载由 segue 事件触发。 在 View Controller 中首先调用什么方法? -(void) viewWillAppear:(BOO
我在某些Django模型中使用JSONField,并希望将此数据从Oracle迁移到Postgres。 到目前为止,当使用Django的dumpdata和loaddata命令时,我仍然没有运气来保持J
创建 Nib 时,我需要创建两种类型:WindowNib 或 ViewNib。我看到的区别是,窗口 Nib 有一个窗口和一个 View 。 如何将 View Nib 加载到另一个窗口中?我是否必须创建
我想将多个env.variables转换为静态结构。 我可以手动进行: Env { is_development: env::var("IS_DEVELOPMENT")
正如我从一个测试用例中看到的:https://godbolt.org/z/K477q1 生成的程序集加载/存储原子松弛与普通变量相同:ldr 和 str 那么,宽松的原子变量和普通变量之间有什么区别吗
我有一个重定向到外部网站的按钮/链接,但是外部网站需要一些时间来加载。所以我想添加一个加载屏幕,以便外部页面在显示之前完全加载。我无法控制外部网站,并且外部网站具有同源策略,因此我无法在 iFrame
我正在尝试为我的应用程序开发一个Dockerfile,该文件在初始化后加载大量环境变量。不知何故,当我稍后执行以下命令时,这些变量是不可用的: docker exec -it container_na
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我刚刚遇到一个问题,我有一个带有一些不同选项的选择标签。 现在我想检查用户选择了哪些选项。 然后我想将一个新的 html 文件加载到该网站(取决于用户选中的选项)宽度 javascript,我该怎么做
我知道两种保存/加载应用程序设置的方法: 使用PersistentStore 使用文件系统(存储,因为 SDCard 是可选的) 我想知道您使用应用程序设置的做法是什么? 使用 PersistentS
我开始使用 Vulkan 时偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的英特尔 hd vulkan 驱动程序上可用,至少它是这么说的),它没有告诉我 vkCreateDeb
我是一名优秀的程序员,十分优秀!