轩辕十四

探索科技与创新的个人博客

后台进程类型

在 macOS 中有四种类型的后台进程。不同之处在下表中进行了总结,并在下面的小节中进行了详细描述。要选择适当类型的后台进程,请考虑以下事项:

  • 它是针对当前登录的用户还是针对所有用户执行某些操作。
  • 它是由单个应用程序使用还是由多个应用程序使用。
  • 它是否需要显示用户界面或启动GUI应用程序。
类型 由 launchd 管理? 在哪种环境下运行 可以显示 UI 吗
Login item 用户
XPC service 用户 否(除非以非常有限的方式使用IOSurface)
Launch Daemon 系统
Launch Agent 用户 不建议
阅读全文 »

监听者 (Listener),连接 (Connection) 和导出对象 (Exported Object)

在 App 端,我们有一个 connection 对象。每次将数据发给 service 时,我们需要调用 remoteObjectProxyWithErrorHandler 方法来创建一个远程对象代理 (remote object proxy)。

而在service端,则多了一层。首先需要一个 listener,用来监听来自 App 的传入 connection。App 可以创建多个 connection,listener 会在 service 端建立相应的 connection 对象。每个 connection 对象都有唯一的 exported object,在 App 端,通过 remote object proxy 发送的消息就是给它的。

阅读全文 »

安装 FFmpeg

根据 官方文档 的描述,有三种安装 FFmpeg 的方式,这里我们选择最简单快速的一种,使用 Homebrew 命令安装。

如果还没有安装 Homebrew 的话,请先安装 Homebrew点击跳转官方网站

我们执行如下命令即可安装好 FFmpeg:

1
brew install ffmpeg
阅读全文 »

Building for iOS Simulator, but the embedded framework ‘xxx.framework’ was built for iOS + iOS Simulator.

升级 Xcode 后就悲剧了,以上报错苹果在 Xcode 11 中已经给出 warring,在 Xcode 12.3 版本后会直接 error。

来自苹果工程师的回复:

This framework isn’t built with a supported configuration – iOS and iOS Simulator code has never been supported in the same binary. The linker in Xcode 11 began identifying these incorrect configurations and issuing warnings, and Xcode 12 goes further in identifying these issues.

The only correct way to resolve this is to rebuild the framework as an XCFramework. If this is your framework, or owned by another group in your company, follow the information in the video and the Xcode Help article.

If this framework is from a vendor, then you need to work with the vendor to get an updated version of the framework built with supported configuration.

In the discussion of this thread, there is a build script that attempts to resolve this error. Scripts like that – anything that tries to manipulate the output with commands like lipo – still produces an unsupported configuration in the binary. XCFrameworks are the way to go.

阅读全文 »

今天在项目中遇到了一个有趣的问题。项目中有一个监听的服务,监听需要将控制器放入一个数组中为其进行相应的操作。不过这引发了一个循环引用的问题。那么问题就变成了,如何在数组中存储弱引用呢?

数组中存储弱引用我们可以有两种解决方式:

  • 设置一个类来存储我们的控制器,这个类的中用于存储的属性自然是 weak 类型。
  • 使用 NSPointerArray
阅读全文 »

今天在工作中遇到了需要让 AVPlayerLayer 支持 autolayout 的问题。因为我播放器的 playerView 是通过约束决定大小的,目的为了适应小屏手机。我需要让我的 AVPlayerLayer 充满我的 playerView,如果有 autolayout 这个问题就非常好解决,但是 layer 是不支持 autolayout 的,我想到了两种解决方式。

阅读全文 »

Carthage 与 Cocoapods 的不同

Cocoapods 是由来已久的 Cocoa 依赖管理工具,那么为什么 Carthage 项目被创建?

首先,Cocoapods(默认情况下)会自动的为你的应用程序和所有依赖创建和更新 Xcode workspace。Carthage 用 xcodebuild 构建框架(framework)的二进制文件,但是并没有将他们整合到用户项目中。Cocoapods 的目的是让用户使用起来更简单,而 Carthage 则是更灵活,减少对项目的侵入性。

Cocoapods 的目标在其README文件中有如下描述:

… to improve discoverability of, and engagement in, third party open-source libraries, by creating a more centralized ecosystem.

对比之下,Carthage 被创建成一个松散(decentralized)的依赖管理者,没有中心项目清单,这减少了维护工作并避免了任何中心故障点(通俗的讲就是去中心化)。然而,项目被发现就变的更加困难 – 用户必须去使用 GitHub 的 Trending 页面或者其他类似的页面(Cocoapods 就比较简单的可以在终端搜索需要使用的库)。

阅读全文 »

函数的定义

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。

1
2
3
4
a = abs
print(a(-1))

output: 1

pass 定义空函数,目的是为了让程序能够跑起来。

1
2
def my_func():
pass
1
2
3
4
5
6
7
8
def my_abs(x):
# 检查传入的参数是否正确,只允许 int 和 float 类型的参数
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
阅读全文 »

字符串

ord() 函数获取字符的 ASCII 码值

1
2
3
4
5
print(ord('a'))
print(ord('A'))

output: 97
output: 65

chr() 函数把 ASCII 转换为对应的字符

1
2
3
4
5
print(chr(66))
print(chr(97))

output: B
output: a
阅读全文 »

我想在之前升级到 macOS Mojave 的同学都会经历过一条命令:

1
defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO

执行如上命令会开启苹果之前的字体渲染方式 – 子像素抗锯齿。因为苹果在 Mojave 系统上启用了新的灰度抗锯齿模式,导致 Chrome 浏览器的字体实在无法直视,有幸今天 Chrome 浏览器更新到 72 版本后修复了这个问题

阅读全文 »
0%