24

我想知道是否有任何体面的方法,除了 NSLog-ing 几乎所有东西 - 在 OS X 中正确调试屏幕保护程序应用程序包?

“屏幕保护程序”是 Xcode 中的一种项目类型,但显然没有 Build and Go 调试。此外,我发现实际上我的包正在加载到

/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app 

应用程序作为某种插件。

那么有没有一种体面的方法来调试你的代码呢?查看崩溃报告和 NSLog-ing 到控制台会有所帮助,但它远非完美。

4

9 回答 9

16

有一篇旧的MacTech文章描述了屏幕保护程序的开发周期。文章还有第 2 部分。查看“调试提示”部分。

我发现这种方法很痛苦,所以我编写了一个应用程序,基本应用程序是一个窗口和一个控制器,它使用我的新屏幕保护程序包初始化 ScreenSaverView。一旦它起作用了,我所要做的就是在 Xcode 中按 Command-R 来测试更改。

于 2009-07-09T13:48:24.957 回答
8

由于 OS X 10.11 El Capitan 的系统完整性保护功能,调试器无法附加到从/System/. 此外,此处的其他信息适用于旧版本的 Xcode。

以下是我使用 Xcode 7.2 在 El Capitan 上工作的方法:

  1. 复制/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/ScreenSaverEngine.app//tmp/. (由于 .xcscheme 引用了完全限定的路径,因此将其复制到共同的某个地方最适合协作,而不是复制到特定用户主目录中的某个地方。)
  2. 编辑项目的.xcscheme
    • 将其运行操作的可执行文件设置为复制的应用程序,并添加参数:(-debug -background -module "<product-name>"其中是不带扩展<product-name>名的包名称)。.saver
    • 添加一个 Pre-action 脚本(下面的源代码),其 shell 设置为/bin/bash,其构建设置来自该方案。它创建一个指向内置.saver包的符号链接~/Library/Screen Savers/

来源:

SCREEN_SAVER_PATH="${HOME}/Library/Screen Savers/${FULL_PRODUCT_NAME}"
if [[ -d "${SCREEN_SAVER_PATH}" || -f "${SCREEN_SAVER_PATH}" || -L "${SCREEN_SAVER_PATH}" ]]; then
    rm -Rf "${SCREEN_SAVER_PATH}"
fi
ln -s "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" "${SCREEN_SAVER_PATH}"

现在,当您点击 Xcode 的 Run 按钮时,屏幕保护程序将在您的桌面上以墙纸模式运行,您可以使用调试器。

于 2016-01-21T16:27:56.257 回答
6

您可以通过执行将加载插件的应用程序来调试插件。

因此,要调试屏幕保护程序,请打开您的插件项目,从“项目”菜单中选择“新建自定义可执行文件”并将应用程序设置为屏幕保护程序引擎。

为了调试屏幕保护程序,您可能还想使用第二台 Mac 并使用远程调试,这样您的用户界面操作就不会干扰屏幕保护程序。

于 2009-07-09T13:20:33.883 回答
3

有一些 Mac OS X 应用程序将运行屏幕保护程序:SaverLab、Screalicious 等。只需在网上找到其中一个并下载它,然后将其设置为目标可执行文件(如 Peter N Lewis 所说)。

为避免在每次构建后将构建产品复制到“~/Library/Screen Savers/”,您可以添加自定义构建脚本(注意:我在 shell 中使用“/bin/tcsh -x”):

#remove the old screen saver or link
rm -Rf "${SCRIPT_OUTPUT_FILE_0}"

#if this is a debug build…
if ("${CONFIGURATION}" == "Debug" ) then

# create a symbolic link from our screen saver to this users screen saver directory
ln -sfv "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"

#if this is a release build…
else if ("${CONFIGURATION}" == "Release" ) then

# copy our screen saver to this users CMM directory
cp -Rfv "${SCRIPT_INPUT_FILE_0}" "${SCRIPT_OUTPUT_FILE_0}"

endif

然后将其输入文件设置为“${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}”,将其输出文件设置为“${HOME}/Library/Screen Savers/${FULL_PRODUCT_NAME}”。

现在,当您构建/运行您的项目时,它会自动神奇地链接到您的调试构建或复制您的发布构建。

于 2012-02-12T02:33:16.630 回答
3

您还可以使屏幕保护程序引擎('/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app')成为目标可执行文件并将 -background 标志传递给它(因此它运行在所有内容的后面而不是所有内容的前面) .

于 2013-05-13T15:19:49.857 回答
2

正如彼得所说,您可以通过执行将加载插件的应用程序来调试插件。

但是,除了使用屏幕保护程序引擎,您还可以使用系统首选项。当首选项出现时,导航到“桌面和屏幕保护程序”下的屏幕保护程序以加载您的插件。

它并不完美,因为您的视图不会是全尺寸的,但它比设置远程调试更容易。

于 2009-07-18T10:25:05.467 回答
1

不一定是最好的方法,但您可以从另一台机器 ssh 并从 gdb 启动 ScreenSaverEngine(未经测试)

编辑

此外,您可以尝试添加一个新的应用程序目标并将您的 ScreenSaverView 添加到 IB 中的窗口,您可能必须手动配置设置等内容,但它可能会有所帮助,并且应该可以正常工作,因为 ScreenSaverView 是 NSView 的子类

于 2009-07-09T05:15:29.453 回答
0

如果您制作 ScreenSaverEngine 应用程序的副本,并使用您的开发人员 ID 对其进行签名,它将修复系统完整性保护阻止附加调试器的情况。只需确保将可执行文件设置为您自己签名的副本。

于 2016-08-12T18:54:44.003 回答
0

我想指出@Karl 的解决方案对我来说效果最好。但是,如果您像我一样每天晚上重新启动计算机,您可能需要考虑放置:

cp -Rn /System/Library/CoreServices/ScreenSaverEngine.app /tmp

在他的回答中提到的 pre-Build shell 脚本的开头。这将自动为您执行复制步骤。

(虽然我相信这确实属于评论,但我的 xp 还不够高)

于 2019-04-09T15:44:57.740 回答