分类: IOS技术

IOS技术

ios 注意权限设置 描述

NSCameraUsageDescription
App需要您的同意,才能访问相机

NSPhotoLibraryUsageDescription
App需要您的同意,才能访问相册

NSMicrophoneUsageDescription
App需要您的同意,才能访问麦克风

NSContactsUsageDescription
App需要您的同意,才能访问通信录

NSLocationUsageDescription
App需要您的同意,才能访问位置

NSLocationWhenInUseUsageDescription
App需要您的同意,才能在使用期间访问位置

NSLocationAlwaysUsageDescription
App需要您的同意,才能始终访问位置

NSCalendarsUsageDescription
App需要您的同意,才能访问日历

NSRemindersUsageDescription
App需要您的同意,才能访问提醒事项

NSMotionUsageDescription
App需要您的同意,才能访问运动与健身

NSHealthUpdateUsageDescription
App需要您的同意,才能访问健康更新

NSHealthShareUsageDescription
App需要您的同意,才能访问健康分享

NSBluetoothPeripheralUsageDescription
App需要您的同意,才能访问蓝牙

NSAppleMusicUsageDescription
App需要您的同意,才能访问媒体资料库

欢迎使用Markdown编辑器
你好! 这是你*次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

全新的界面设计 ,将会带来全新的写作体验;
在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
全新的 KaTeX数学公式 语法;
增加了支持甘特图的mermaid语法1 功能;
增加了 多屏幕编辑 Markdown文章功能;
增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

%title插图%num

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

%title插图%num

如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

1    // An highlighted block
2   var foo = ‘bar’;

生成一个适合你的列表
项目
项目
项目
项目1
项目2
项目3
计划任务
完成任务
创建一个表格
一个简单的表格是这么创建的:

%title插图%num

设定内容居中、居左、居右
使用:———:居中
使用:———-居左
使用———-:居右

%title插图%num

*列 第二列 第三列
*列文本居中 第二列文本居右 第三列文本居左
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

%title插图%num

创建一个自定义列表
Markdown
Text-to- HTML conversion tool
Authors
John
Luke
如何创建一个注脚
一个具有注脚的文本。2

注释也是必不可少的
Markdown将文本转换为 HTML。

KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb NΓ(n)=(n−1)!∀n∈N 是通过欧拉积分

%title插图%num

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

%title插图%num

关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

%title插图%num

 

  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

关于 Flowchart流程图 语法,参考 这儿.

%title插图%num
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。

mermaid语法说明 ↩︎

注脚的解释 ↩︎

iOS10 审核 NSCameraUsageDescription 等描述问题

iOS10后 提交审核经常会因为没有在info.plist文件里边加入访问隐私的提醒而被回退,这样子又浪费了时间,所以先对照一下APP中是否用到这些隐私的权限

通讯录
NSContactsUsageDescription (XXX想访问您的通讯录,允许吗?)

通讯录
Contacts Usage Description (XXX想访问您的通讯录,允许吗?)

麦克风
NSMicrophoneUsageDescription (XXX想使用您的麦克风,允许吗?)

相册
NSPhotoLibraryUsageDescription (XXX想访问您的相册,允许吗?)

相机
NSCameraUsageDescription (XXX想使用您的相机,允许吗?)

地理位置(一直开启)
NSLocationAlwaysUsageDescription (XXX想使用您的地理位置,允许吗?)

地理位置(使用时开启)
NSLocationWhenInUseUsageDescription (XXX想使用您的地理位置,允许吗?)

蓝牙权限
Bluetooth Peripheral Usage Description (XXX想使用您的蓝牙,允许吗?)

语音转文字权限
Speech Recognition Usage Description (XXX请求语音转文字权限,允许吗?)

日历权限
Calendars Usage Description (XXX想使用您的日历,允许吗?)

健康应用(更新)
Health Update Usage Description (XXX想访问您的HealthKit,允许吗?)

健康应用(读取)
Health Share Usage Description (XXX想访问您的HealthKit,允许吗?)

APP支持文件共享设置(iOS)

在开发过程中,有时候需要手动放一些文件到Documents文件夹下做测试,以前是可以直接用itools或者PP助手等工具直接拖拉文件到Documents文件夹的,但是*近开发时发现不可以这样子做了,必须先配置一下开发的APP

方法:

在应用程序的Info.plist文件中添加Application supports iTunes file sharing键,并将键值设置为YES。
这样子配置后,用itunes就能见到该APP出现在能进行文件共享的列表中,但是发现itunes不能将文件拖进代码创建好的文件夹中,用PP助手就可以了。

iOS App文件共享

通过UIDocumentInteractionController或者是QLPreviewController来预览PDF等格式文件的时候,我们可以通过自带的UIActivityViewController把该文件共享出去或进行打印等处理。如图所示:

*行的AirDrop是iOS7之后给用户提供的一种在苹果设备之间共享文件的快捷方式,类似于安卓上的蓝牙无线传输文件。

第二行是通过文档类型关联技术识别的App的列表。

第三行是通过文档关联技术识别的Action的列表,表示对文件可进行的一些操作,如复制,打印,保存等。

我们知道在iOS系统下有一种安全体系–沙盒机制,每个iOS应用程序都是一个独立的文件系统,并且只能在自己的文件系统进行操作,所以iOS系统下并不能像安卓一样轻松取到其他应用程序下的文件。

既然我们能在自己的应用程序下预览文件时把文件共享到其他App中,那么反过来怎么能让其他App共享文件到我们App呢?

info.plist注册文件类型
我们需要在info.plist文件中,添加一个新的属性CFBundleDocumentTypes(实际上输入的是Document type),这是一个数组类型的属性,意思就是我们可以同时注册多个类型。而针对数组中的每一个元素,都有许多属性可以指定,详细的属性列表我们可以从官方文档上找到: Core Foundation Keys —- CFBundleDocumentTypes。这里列举我们在做iOS开发时常用的属性:

CFBundleTypeName

字符串类型,指定某种类型的别名,也就是用来指代我们规定的类型的别称,一般为了保持唯一性,我们使用UTI来标识。

CFBundleTypeIconFiles
数组类型,包含指定的png图标的文件名,指定代表某种类型的图标,而图标有具体的尺寸标识:

Device Sizes
iPad 64 x 64 pixels, 320 x 320 pixels
iPhone and iPod touch 22 x 29 pixels, 44 x 58 pixels (high resolution)
* LSItemContentTypes

数组类型,包含UTI字符串,指定我们的应用程序所有可以识别的文件类型集合
* LSHandlerRank
字符串类型,包含Owner,Default,Alternate,None四个可选值,指定对于某种类型的优先权级别,而Launcher Service会根据这个优先级别来排列显示的App的顺序。优先级别从高到低依次是Owner,Alternate,Default。None表示不接受这种类型。

我们选择Source code方式打开info.plist文件添加以下代码:

1 <key>CFBundleDocumentTypes</key>
2     <array>
3         <dict>
4             <key>CFBundleTypeName</key>
5             <string>PDF</string>
6             <key>LSHandlerRank</key>
7             <string>Owner</string>
8             <key>LSItemContentTypes</key>
9             <array>
10                 <string>com.adobe.pdf</string>
11             </array>
12         </dict>
13         <dict>
14             <key>CFBundleTypeName</key>
15             <string>Microsoft Word</string>
16             <key>LSHandlerRank</key>
17             <string>Alternate</string>
18             <key>LSItemContentTypes</key>
19             <array>
20                 <string>com.microsoft.word.doc</string>
21                 <string>com.microsoft.word.wordml</string>
22                 <string>org.openxmlformats.wordprocessingml.document</string>
23             </array>
24         </dict>
25         <dict>
26             <key>CFBundleTypeName</key>
27             <string>Microsoft Excel</string>
28             <key>LSHandlerRank</key>
29             <string>Alternate</string>
30             <key>LSItemContentTypes</key>
31             <array>
32                 <string>com.microsoft.excel.xls</string>
33                 <string>org.openxmlformats.spreadsheetml.sheet</string>
34             </array>
35         </dict>
36         <dict>
37             <key>CFBundleTypeIconFiles</key>
38             <array/>
39             <key>CFBundleTypeName</key>
40             <string>Microsoft PowerPoint</string>
41             <key>LSHandlerRank</key>
42             <string>Alternate</string>
43             <key>LSItemContentTypes</key>
44             <array>
45                 <string>com.microsoft.powerpoint.​ppt</string>
46                 <string>org.openxmlformats.presentationml.presentation</string>
47                 <string>public.presentation</string>
48             </array>
49         </dict>
50         <dict>
51             <key>CFBundleTypeName</key>
52             <string>Text</string>
53             <key>LSHandlerRank</key>
54             <string>Alternate</string>
55             <key>LSItemContentTypes</key>
56             <array>
57                 <string>public.text</string>
58                 <string>public.plain-text</string>
59                 <string>public.utf8-plain-text</string>
60                 <string>public.utf16-external-plain-​text</string>
61                 <string>public.utf16-plain-text</string>
62                 <string>com.apple.traditional-mac-​plain-text</string>
63                 <string>public.source-code</string>
64                 <string>public.c-source</string>
65                 <string>public.objective-c-source</string>
66                 <string>public.c-plus-plus-source</string>
67                 <string>public.objective-c-plus-​plus-source</string>
68                 <string>public.c-header</string>
69                 <string>public.c-plus-plus-header</string>
70                 <string>com.sun.java-source</string>
71                 <string>public.script</string>
72                 <string>public.shell-script</string>
73             </array>
74         </dict>
75         <dict>
76             <key>CFBundleTypeName</key>
77             <string>Rich Text</string>
78             <key>LSHandlerRank</key>
79             <string>Alternate</string>
80             <key>LSItemContentTypes</key>
81             <array>
82                 <string>public.rtf</string>
83                 <string>com.apple.rtfd</string>
84                 <string>com.apple.flat-rtfd</string>
85             </array>
86         </dict>
87         <dict>
88             <key>CFBundleTypeName</key>
89             <string>HTML</string>
90             <key>LSHandlerRank</key>
91             <string>Alternate</string>
92             <key>LSItemContentTypes</key>
93             <array>
94                 <string>public.html</string>
95                 <string>public.xhtml</string>
96             </array>
97         </dict>
98         <dict>
99             <key>CFBundleTypeName</key>
100             <string>Web Archive</string>
101             <key>LSHandlerRank</key>
102             <string>Alternate</string>
103             <key>LSItemContentTypes</key>
104             <array>
105                 <string>com.apple.webarchive</string>
106             </array>
107         </dict>
108         <dict>
109             <key>CFBundleTypeName</key>
110             <string>Image</string>
111             <key>LSHandlerRank</key>
112             <string>Alternate</string>
113             <key>LSItemContentTypes</key>
114             <array>
115                 <string>public.image</string>
116             </array>
117         </dict>
118         <dict>
119             <key>CFBundleTypeName</key>
120             <string>iWork Pages</string>
121             <key>LSHandlerRank</key>
122             <string>Alternate</string>
123             <key>LSItemContentTypes</key>
124             <array>
125                 <string>com.apple.page.pages</string>
126                 <string>com.apple.iwork.pages.pages</string>
127                 <string>com.apple.iwork.pages.template</string>
128             </array>
129         </dict>
130         <dict>
131             <key>CFBundleTypeName</key>
132             <string>iWork Numbers</string>
133             <key>LSHandlerRank</key>
134             <string>Alternate</string>
135             <key>LSItemContentTypes</key>
136             <array>
137                 <string>com.apple.numbers.numbers</string>
138                 <string>com.apple.iwork.numbers.numbers</string>
139                 <string>com.apple.iwork.numbers.template</string>
140             </array>
141         </dict>
142         <dict>
143             <key>CFBundleTypeName</key>
144             <string>iWork Keynote</string>
145             <key>LSHandlerRank</key>
146             <string>Alternate</string>
147             <key>LSItemContentTypes</key>
148             <array>
149                 <string>com.apple.keynote.key</string>
150                 <string>com.apple.iwork.keynote.key</string>
151                 <string>com.apple.iwork.keynote.kth</string>
152             </array>
153         </dict>
154         <dict>
155             <key>CFBundleTypeName</key>
156             <string>Audio</string>
157             <key>LSHandlerRank</key>
158             <string>Alternate</string>
159             <key>LSItemContentTypes</key>
160             <array>
161                 <string>public.audio</string>
162             </array>
163         </dict>
164         <dict>
165             <key>CFBundleTypeName</key>
166             <string>Movie</string>
167             <key>LSHandlerRank</key>
168             <string>Alternate</string>
169             <key>LSItemContentTypes</key>
170             <array>
171                 <string>public.movie</string>
172             </array>
173         </dict>
174         <dict>
175             <key>CFBundleTypeName</key>
176             <string>Archive</string>
177             <key>LSHandlerRank</key>
178             <string>Alternate</string>
179             <key>LSItemContentTypes</key>
180             <array>
181                 <string>public.archive</string>
182             </array>
183         </dict>
184     </array>

添加这些代码,你的App就可以支持大部分文件类型了,可以根据自己项目的需求,添加相关类型的代码,像我自己的项目只需要支持PDF和word格式的文件。添加完这些代码,我们选择Property list打开info.plist文件:

或者在info页面打开Document types列表

这个时候就代表我们已经成功的注册好了App支持的文件类型,这个时候我们在编译运行,然后再到其他App(我这边用的QQ)打开下载好的文件,这个时候出来的页面是这样的:

我们可以看到自己的App图标已经出现在第二栏的列表中,这个时候我们点击图标按钮即可把文件共享到自己App中。

如何处理共享文件
当点击图标按钮的时候,会跳转到我们自己的应用程序中,这个时候在AppDelegate.m会走- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options该回调方法。

但是在iOS9之前回调的是- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation,所以我们需要针对不同的设备版本做出改变。

我们可以在回调方法里进行文件处理操作,如将文件上传、文件预览、文件保存一些工作。在做文件预览的时候我们必定得跳转到对应的控制器中,这个时候我们首先得获取到当前的视图控制器

1 //获取当前屏幕显示的viewcontroller
2 – (UIViewController *)getCurrentVC
3 {
4     UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
5
6     UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
7
8     return currentVC;
9 }
10
11 – (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
12 {
13     UIViewController *currentVC;
14
15     if ([rootVC presentedViewController]) {
16         // 视图是被presented出来的
17
18         rootVC = [rootVC presentedViewController];
19     }
20
21     if ([rootVC isKindOfClass:[UITabBarController class]]) {
22         // 根视图为UITabBarController
23
24         currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
25
26     } else if ([rootVC isKindOfClass:[UINavigationController class]]){
27         // 根视图为UINavigationController
28
29         currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
30
31     } else {
32         // 根视图为非导航类
33
34         currentVC = rootVC;
35     }
36
37     return currentVC;
38 }

拿到控制器我们可以回到回调方法里进行跳转工作,我这边还是用UIDocumentInteractionController做文件预览

1 #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
2 – (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
3     // 判断传过来的url是否为文件类型
4     if ([url.scheme isEqualToString:@”file”]) {
5         _docVc = [UIDocumentInteractionController interactionControllerWithURL:url];
6         _docVc.delegate = self;
7         [_docVc presentPreviewAnimated:YES];
8
9     }
10
11 }
12
13 #else
14 – (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
15     // 判断传过来的url是否为文件类型
16     if ([url.scheme isEqualToString:@”file”]) {
17         _docVc = [UIDocumentInteractionController interactionControllerWithURL:url];
18         _docVc.delegate = self;
19         [_docVc presentPreviewAnimated:YES];
20     }
21     return YES;
22 }
23 #endif
24
25 #pragma mark — UIDocumentInteractionControllerDelegate
26 – (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
27 {
28     // 返回当前控制器
29     return [self getCurrentVC];
30 }

 

iOS14,删个 APP 需要点三次,苹果公司是怎么想的?

才发现在资源库里,长按图标,弹出的菜单里选择删除,iOS14 就问一次,点确定就删除了。

45 条回复    2021-03-27 10:33:47 +08:00
mh
    1

mh   22 小时 36 分钟前

不是两次么
whileFalse
    2

whileFalse   22 小时 35 分钟前   ❤️ 1

你删除 APP 的频率有多高?
hash
    3

hash   22 小时 34 分钟前   ❤️ 1

*后一次确认确实意义非常有限
hlobo
    4

hlobo   22 小时 33 分钟前 via Android   ❤️ 30

少用那些,装上用 15 分钟就删掉的 app,注意身体
stark123
    5

stark123   22 小时 30 分钟前

@whileFalse 我才转到 iOS 上。下载了很多 APP 试验,不好的就都删掉。今天删了 40 多个了。
xnotepad
    6

xnotepad   22 小时 29 分钟前

装个 APP 还得按两次关闭按钮呢。这样一比,是不是觉得你那个三次点击也就没啥了。
superrichman
    7

superrichman   22 小时 26 分钟前 via iPhone

你就当多点一下是帮你清空数据好了,ios 不会跟安卓一样删了 app 还留一堆乱七八糟的文件夹
MidAutumnMoon
    8

MidAutumnMoon   22 小时 23 分钟前 via iPhone

确实现在的操作不如以前那样自然,这方面 iOS 就像走了倒车似的( imo )
finab
    9

finab   22 小时 20 分钟前   ❤️ 1

嘿嘿,我可以压缩到俩次~
按住 弹出菜单后手指滑到删除按钮再松开,再点确认~
deplives
    10

deplives   22 小时 19 分钟前 via iPhone   ❤️ 3

两次吧你就要问 为啥删除前不确认一次,万一误删除咋办,三次吧又问为啥还要点三次,
现在就差直接读取你脑子里的想法了,这样一次也不用点

 

dingdangnao
    11

dingdangnao   22 小时 19 分钟前

真心觉得 iOS 的某些交互需要改改了。。。比如左上角返回。。MAX 一只手根本点不到左上角。。
(尤其国内某些垃圾 app 没有左滑返回,只能点左上角

iOS 的主界面的图标,iPhone 12 Pro Max 只比 iPhone 5 多了一排。。。傻大笨的感觉。。哎

whileFalse
    12

whileFalse   22 小时 8 分钟前

@stark123 特别想知道你是怎么样点 3 次才删除的。我都是两次。
Astrian
    13

Astrian   22 小时 2 分钟前

我猜你是通过按住图标会出现 context menu 里面的删除按钮来删除 app……
弹出 context menu 继续按住就会变成经典的抖图标
flineqaq
    14

flineqaq   22 小时 0 分钟前 via iPhone

3 次很多么……你把发这个帖子的点击次数省下来,按 2 次的指标够用十几年了╮( ̄▽ ̄””)╭
so898
    15

so898   21 小时 47 分钟前

@dingdangnao 把 Home Indicator (底部的那个横条)往下拨动一下会有惊喜
JoJoJoJ
    16

JoJoJoJ   21 小时 46 分钟前 via iPhone

google 的 hangout,删除一条短信要按 6 次
kop1989
    17

kop1989   21 小时 41 分钟前

主要是多了一个资源库( app 抽屉)。所以要确认你是要删除 app,还是删除桌面图标。
icyalala
    18

icyalala   21 小时 31 分钟前

@mh @finab @whileFalse
两次是怎么做到的?

*种方法:
1. 按住图标出现菜单,滑动到 “移除 App”
2. 在弹出的菜单中点击 “删除 App”
3. 在弹出的菜单中点击 “删除”

第二种方法:
1. 长按图标出现抖动
2. 点左上角的减号
3. 在弹出的菜单中点击 “删除 App”
4. 在弹出的菜单中点击 “删除”

感觉这套东西都是在出现了 App 资源库之后弄得一坨补丁

safarigu
    19

safarigu   21 小时 28 分钟前

感觉现在苹果 iOS 产品做得真的挺差的,该换人换人吧?
更别提 Apple TV app 要多蹩脚有多蹩脚
stark123
    20

stark123   21 小时 25 分钟前

@JoJoJoJ 6 次,这是什么天才逻辑
minami
    21

minami   21 小时 19 分钟前   ❤️ 1

苹果公司怎么想不重要,重要的是果粉怎么想。既然果粉都不觉得是个问题,那么就不是个问题。你看是不是有种哲理在里面
wovfeng
    22

wovfeng   20 小时 32 分钟前 via iPhone   ❤️ 1

说一个小众的删除方法,还可以在 app store 更新那边左滑删除。有时候发现 app 更新了,但好像有没怎么用就顺手删掉了…
petercui
    23

petercui   20 小时 2 分钟前   ❤️ 1

@xnotepad 两次握手,三次挥手。
JHExp
    24

JHExp   19 小时 56 分钟前

开关推送不能快捷操作感觉是*困扰的
wclebb
    25

wclebb   19 小时 40 分钟前 via iPhone

长按—移除,就两次啊?
From313
    26

From313   19 小时 29 分钟前

资源库搜索列表的 App 不能直接删,我是拖拽到桌面删….
ntcydia
    27

ntcydia   19 小时 27 分钟前

在两次删除 app 这个操作上 3D touch 确实是个好功能。
dingdangnao
    28

dingdangnao   19 小时 17 分钟前

@so898 是 确实有所谓的“便捷访问”什么的,你可以去试试看 max 机型, 拇指能不能够得到屏幕一半*左边?
zbatman
    29

zbatman   17 小时 15 分钟前 via Android

是你不会用吧,苹果的设计师不比你懂手机?[狗头]
kiripeng
    30

kiripeng   17 小时 12 分钟前

苹果就是把用户当孙子,而*新的苹果手机对用户的政策是当傻子。( mac 在手我还是这么说)
minamike
    31

minamike   17 小时 0 分钟前 via iPhone

@From313 可以删的 列表里长按图标出现菜单就能删除了
appstore54321
    32

appstore54321   16 小时 44 分钟前 via iPhone

还不是你不会用.jpg

果粉怎么回事?

youcandoit
    33

youcandoit   16 小时 36 分钟前 via iPhone

@hlobo #4 这是什么梗啊……
drawstar
    34

drawstar   16 小时 4 分钟前 via iPhone

@whileFalse 每次进入贤者时间 doge
felixcode
    35

felixcode   15 小时 55 分钟前   ❤️ 1

*近学到了一个超好用的句型:

你们扪心自问一下,你真的需要只点两次就删除 APP 吗?

stark123
    36

stark123   15 小时 46 分钟前

@felixcode 不试用怎么知道是否合适。不合适难道留着过年?
hkezh
    37

hkezh   15 小时 25 分钟前 via iPhone   ❤️ 1

应该给一个资源库开关,不是所有人都喜欢
stark123
    38

stark123   15 小时 17 分钟前

@hkezh 那玩意我非常讨厌。根本用不上。
SenLief
    39

SenLief   15 小时 11 分钟前

苹果的用意是让用户形成习惯,习惯就好了,毕竟我觉得我是对的。
orangy
    40

orangy   14 小时 22 分钟前 via iPhone

@JHExp 长按消息,右上角会出现三点,点击三点,就可以管理该条消息 app 的推送设置了,你是指这个快捷操作吗??
5966
    41

5966   12 小时 33 分钟前 via iPhone

当你在 Safari 打开很多标签,想全部关闭,1,Safari 长按右下角图标,弹出,2,关闭 n 个标签页,还没有完,3,确认关闭吗?
stark123
    42

stark123   11 小时 52 分钟前

@5966 哈哈哈,这逻辑,够 2 的。
daerzei
    43

daerzei   11 小时 23 分钟前 via iPhone

我收集限免应用(下完就删)时体会到了,那个资源库确实没卵用还憨憨,以前确认一下就删了,现在点错了还得去资源库找
littlewing
    44

littlewing   11 小时 19 分钟前

@daerzei 不用真的下载吧,直接点一下,然后取消下载
rcw
    45

rcw   18 分钟前 via iPhone

可能苹果觉得你不会经常删 app

iOS开发-GCD技术

文章目录
前言
Dispatch Queue
Queue Create
Queue Release
MRC
ARC
Global Queue
如何设置QOS级别
Dispatch Set Target
dispatch_after
GCD timer
Dispatch Group
dispatch_group_notify
dispatch_group_wait
dispatch_barrier_async
dispatch_apply
dispatch_resume/dispatch_suspend
dispatch TLS
前言
对于OS X和iOS的XNU内核线程切换时,会进行上下文切换,例如CPU的寄存器等信息保存到各自路径专用的内存块中,从切换目标路径专用的内存块中,复原CPU寄存器等信息,继续执行切换路径的CPU命令行。这被称为“上下文切换”。

使用多线程的程序可以在某个线程和其他线程之间反复多次进行上下文切换,因此看上去就好像1个CPU核能够并列的执行多个线程一样。而且在具有多个CPU核的情况下,就不是“看上去像”了,而是真的提供了多个CPU核并行执行多个线程的技术。

多线程编程易发生各种问题,例如多个线程对资源的竞争,多个线程之间相互等待造成死锁,以及线程开辟消耗大量的内存等问题。

%title插图%num

多线程的优点在于能够将复杂的处理独立出来,不会阻塞主线程这种线程的执行

%title插图%num

GCD是基于XNU内核的线程技术,大大简化了多线程编程的源码。

Dispatch Queue
一般来说我们会这样异步执行一个任务

1   dispatch_async(queue,^{
2  //do your task
3  });

queue代表一个队列,在GCD中存在两种队列形式

Serial Dispatch Queue 串行队列
Concurrent Dispatch Queue 并行队列
两种队列的在于,Serial处理task是根据队列先进先出顺序执行,会保证上一个task执行完再执行下一个,而Concurrent则是并发执行,不会等上一个task执行完

%title插图%num

虽然Concurrent Dispatch Queue不用等待处理结束,可以并发执行多个task,但是其并发线程的数量却是取决于当前系统的状态。根据如下:

iOS和OS X基于Dispatch Queue中的处理数
CPU核数以及CPU负荷等当前系统的状态
来决定Concurrent Dispatch Queue中线程数量。

例如:

1    dispatch_asyc(queue,blk0)
2   //.. 1 ~ 6
3   dispatch_asyc(queue,blk7)

8个task可能根据当前系统的状态,会如下执行:

%title插图%num

Queue Create
我们可以通过GCD的API来生成Dispatch Queue

dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create(“com.example.gcd.MySerialDispatchQueue”,DISPATCH_QUEUE_SERIAL)

值得注意的是Serial Dispatch Queue的生成,当创建一个Serial Dispatch Queue,系统就默认只生成并使用一个线程。如果生成了2000个Serial Dispatch Queue那么就创建2000个线程,这对内存资源消耗是很大的。而Concurrent Dispatch Queue就没这个问题,他会根据系统状态来管理并发线程数量,所以虽然我们可以使用创建多个Serial Dispatch Queue来达到并发的目的,但是并不是GCD的初衷,我们应该使用Concurrent Dispatch Queue来处理并发任务

同样我们可以创建 Concurrent Dispatch Queue

dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create(“com.example.gcd.MyConcurrentDispatchQueue”,DISPATCH_QUEUE_CONCURRENT)

即第二个参数决定了Queue的类型是 Serial 还是 Concurrent

Queue Release
MRC
对于Dispatch Queue,Queue必须创建后由程序员自己释放,因为Dispatch Queue并没有像block那样具有作为Object-C对象来处理的技术。

dispatch_release(myConcurrentDispatchQueue)

但是,Dispatch Queue同样有引用计数管理。意味着你可以

dispatch_retain(myConcurrentDispatchQueue)

例如下面代码

dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create(“com.example.gcd.MyConcurrentDispatchQueue”,DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myConcurrentDispatchQueue, ^{
//do your task
});
dispatch_release(myConcurrentDispatchQueue);

既然dispatch_release释放掉了,为什么任务还能执行,这也是因为block对queue进行了引用,就相当于调用了dispatch_retain

ARC
对于ARC模式下,你不需要手动调用dispatch_release(myConcurrentDispatchQueue);,ARC已经允许将Dispatch Queue作为对象加入ARC内存管理。

Global Queue
我们可以获取系统为我们提供的标准Global Queue,

在iOS 7之前,系统提供了4种优先级,以调度优先级区分

名称 执行优先级
DISPATCH_QUEUE_PRIORITY_HIGH 高(*高优先)
DISPATCH_QUEUE_PRIORITY_DEFAULT 默认
DISPATCH_QUEUE_PRIORITY_LOW 低
DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台
在iOS 8之后,系统提供了5种优先级,以服务质量划分的

名称 执行优先级
QOS_CLASS_USER_INTERATCTIVE 高(*高优先)
QOS_CLASS_USER_INITIATED 用户交互(不要使用耗时操作)
QOS_CLASS_DEFAULT 默认
QOS_CLASS_UTILITY 使用工具(用了做耗时操作)
QOS_CLASS_BACKGROUND 后台执行
QOS_CLASS_UNSPECIFIED 没有指定优先级
对于QOS_CLASS_UTILITY我们一般进行耗时操作,例如数据I/O,系统对其进行了优化,使得能够减少App的电量消耗。

如何设置QOS级别
dipatch_queue_attr_make_with_qos_class 或dispatch_set_target_queue方法设置队列的优先级

1 //dipatch_queue_attr_make_with_qos_class
2
3 dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, -1);
4
5 dispatch_queue_t queue = dispatch_queue_create(“com.starming.gcddemo.qosqueue”, attr);
6
7
8
9 //dispatch_set_target_queue
10
11 dispatch_queue_t queue = dispatch_queue_create(“com.starming.gcddemo.settargetqueue”,NULL); //需要设置优先级的queue
12
13 dispatch_queue_t referQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); //参考优先级
14
15 dispatch_set_target_queue(queue, referQueue); //设置queue和referQueue的优先级一样

Dispatch Set Target
void dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t _Nullable queue);

dispatch_set_target_queue能够设置queue的执行阶层,无论是Concurrent Queue还是Serial Queue,一旦设置target为Serial Queue就是串行执行。

例如下列代码:

1 – (void)set_tag_test {
2     dispatch_queue_t serialQueue1 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue1”, DISPATCH_QUEUE_CONCURRENT);
3     dispatch_queue_t serialQueue2 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue2”, DISPATCH_QUEUE_CONCURRENT);
4     dispatch_queue_t serialQueue3 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue3”, DISPATCH_QUEUE_CONCURRENT);
5     dispatch_queue_t serialQueue4 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue4”, DISPATCH_QUEUE_CONCURRENT);
6     dispatch_queue_t serialQueue5 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue5”, DISPATCH_QUEUE_CONCURRENT);
7
8
9
10     //创建目标串行队列
11     dispatch_queue_t targetSerialQueue = dispatch_queue_create(“com.gcd.setTargetQueue2.targetSerialQueue”, NULL);
12
13     //设置执行阶层
14     dispatch_set_target_queue(serialQueue1, targetSerialQueue);
15     dispatch_set_target_queue(serialQueue2, targetSerialQueue);
16     dispatch_set_target_queue(serialQueue3, targetSerialQueue);
17     dispatch_set_target_queue(serialQueue4, targetSerialQueue);
18     dispatch_set_target_queue(serialQueue5, targetSerialQueue);
19
20     dispatch_async(serialQueue1, ^{
21         NSLog(@”%@,1″,[NSThread currentThread]);
22     });
23     dispatch_async(serialQueue1, ^{
24         NSLog(@”%@,1 2″,[NSThread currentThread]);
25     });
26     dispatch_async(serialQueue2, ^{
27         NSLog(@”%@,2″,[NSThread currentThread]);
28     });
29     dispatch_async(serialQueue3, ^{
30         NSLog(@”%@,3″,[NSThread currentThread]);
31     });
32     dispatch_async(serialQueue4, ^{
33         NSLog(@”%@,4″,[NSThread currentThread]);
34     });
35     dispatch_async(serialQueue5, ^{
36         NSLog(@”%@,5″,[NSThread currentThread]);
37     });
38     dispatch_async(targetSerialQueue, ^{
39         NSLog(@”%@,6″,[NSThread currentThread]);
40     });
41 }

输出为:

1 <NSThread: 0x60000239b580>{number = 3, name = (null)},1
2 <NSThread: 0x60000239b580>{number = 3, name = (null)},1 2
3 <NSThread: 0x60000239b580>{number = 3, name = (null)},2
4 <NSThread: 0x60000239b580>{number = 3, name = (null)},3
5 <NSThread: 0x60000239b580>{number = 3, name = (null)},4
6 <NSThread: 0x60000239b580>{number = 3, name = (null)},5
7 <NSThread: 0x60000239b580>{number = 3, name = (null)},6

dispatch_after
延迟执行

1     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);
2     dispatch_after(time, dispatch_get_main_queue(),^{
3         //do task
4     });

dispatch_after是延迟3s加入Dispatch Queue,并不是马上执行,例如加入到主线程时,如果主线程卡段,这个延迟会大于3s

某一*对时间执行
如果dispatch_after需要在2020/04/27 11:11:11执行,那么dispatch_time_t就可以使用dispatch_walltime构造

 

1   dispatch_time_t dispatch_walltime(const struct timespec *_Nullable when, int64_t delta);

1     NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
2     struct timespec time;
3     dispatch_time_t milestone;
4     double second,subsecond;
5     subsecond = modf(interval, &second);
6     time.tv_sec = second;
7     time.tv_nsec = subsecond * NSEC_PER_SEC;
8     milestone = dispatch_walltime(&time, 0);

GCD timer
1  void
2  dispatch_source_set_timer(dispatch_source_t source, //source timer
3  dispatch_time_t start, //开始时间
4  uint64_t interval, //执行间隔
5  uint64_t leeway); //允许的延迟时间 – 系统会尽量满足,但不一定保证在延迟时间内执行

一般来说我们定时器这样写:

1     timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
2     dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, (80 * NSEC_PER_MSEC)), (80 * NSEC_PER_MSEC), 0);
3     dispatch_source_set_event_handler(timer, ^{
4         //
5     });
6     dispatch_resume(timer);

注意dispatch_source是遵循ARC的,要强引用保证其不被释放。

为什么GCD定时器相比NSTimer定时器更准?
NSTimer是CFRunLoopTimerRef的toll-free bridged的,可以直接转换,当某一次执行被延后,错过了时间点,那么NSTimer会选择不执行此次回调,等到下次执行。所以相比来说,GCD定时器更为准确。

此外 GCD定时器无法保证每次的执行同时在一个线程中,就算是Serial队列也不行,而NSTimer是加入到线程的runloop中,所以必定是同一个线程,当我们需要单线程执行时,需要注意这点。

Dispatch Group
dispatch_group_notify
我们一般用dispatch_group处理多个任务完成后,执行某个操作

1 – (void)dispatch_group_test {
2     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
3     dispatch_group_t group = dispatch_group_create();
4     dispatch_group_async(group, queue, ^{
5         NSLog(@”blk0;”);
6     });
7     dispatch_group_async(group, queue, ^{
8         NSLog(@”blk1;”);
9     });
10     dispatch_group_async(group, queue, ^{
11         NSLog(@”blk2;”);
12     });
13
14     //1. notify
15     dispatch_group_notify(group, dispatch_get_main_queue(), ^{
16         NSLog(@”done”);
17     });
18
19     //MRC
20 //    dispatch_release(group);
21 }

控制台输出为:

1 2020-04-29 16:30:20.748658+0800 GCDTest[51629:2202347] blk0;
2 2020-04-29 16:30:20.748668+0800 GCDTest[51629:2202345] blk1;
3 2020-04-29 16:30:20.748687+0800 GCDTest[51629:2202346] blk2;
4 2020-04-29 16:30:20.761685+0800 GCDTest[51629:2201079] done

追加到Dispatch Group的block会对Dispatch Group进行dispatch_retain并持有,在block 执行完之后释放Dispatch Group,所以一旦Dispatch Group使用结束,意味着block都不保持其引用了,可以放心释放。

dispatch_group_wait
判断指定时间后,task是否执行完,使用dispatch_group_wait

将上面1部分替换为:

1
2     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);
3     long result = dispatch_group_wait(group, time);
4
5     if (result == 0) {
6         // Group 中task全部执行完
7     }else {
8         // Group 中task还在执行中
9     }

我们可以通过将time参数设置为DISPATCH_TIME_NOW,然后在Runloop每次循环中来判断task是否执行完,以达到和dispatch_group_notify同样的效果。

我们可以通过将time参数设置为DISPATCH_TIME_FOREVER来保证任务一定执行完成。等同于dispatch_group_notify

dispatch_barrier_async
对于访问数据库文件,我们要避免数据竞争,资源是互斥的。虽然我们可以使用Serial Dispatch Queue来解决这样的问题,但是为了高效处理,写入操作确实不可与其他写入以及读取操作同时进行,但是多个读取操作时可以同时进行的,只需要保证写入是在多个读取之后进行。

1 – (void)dispatch_barrier_test {
2     dispatch_queue_t queue = dispatch_queue_create(“com.example.gcd.barrier”, DISPATCH_QUEUE_CONCURRENT);
3     dispatch_async(queue, ^{
4         NSLog(@”read 0″);
5     });
6     dispatch_async(queue, ^{
7         NSLog(@”read 1″);
8     });
9     dispatch_async(queue, ^{
10         NSLog(@”read 2″);
11     });
12     dispatch_barrier_async(queue, ^{
13         NSLog(@”write”);
14     });
15     dispatch_async(queue, ^{
16         NSLog(@”read 3″);
17     });
18     dispatch_async(queue, ^{
19         NSLog(@”read 4″);
20     });
21     dispatch_async(queue, ^{
22         NSLog(@”read 5″);
23     });
24 }

这样就可以保证多次并发read

1 2020-04-29 17:45:00.149982+0800 GCDTest[56002:2263229] read 2
2 2020-04-29 17:45:00.149982+0800 GCDTest[56002:2263230] read 0
3 2020-04-29 17:45:00.149999+0800 GCDTest[56002:2263239] read 1
4 2020-04-29 17:45:00.150130+0800 GCDTest[56002:2263239] write
5 2020-04-29 17:45:00.150215+0800 GCDTest[56002:2263239] read 3
6 2020-04-29 17:45:00.150220+0800 GCDTest[56002:2263230] read 4
7 2020-04-29 17:45:00.150234+0800 GCDTest[56002:2263229] read 5

dispatch_apply
当我们需要将一个block加入到queue中,并多次执行时,使用dispatch_apply,dispatch_apply会阻塞当前线程,并等待queue执行完成。

1 – (void)dispatch_apply_test {
2     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3     dispatch_apply(10, queue, ^(size_t index) {
4         NSLog(@”%zu”,index);
5     });
6     NSLog(@”done”);
7 }

输出为:

1 2020-04-29 18:00:27.838731+0800 GCDTest[56107:2271775] 0
2 2020-04-29 18:00:27.838739+0800 GCDTest[56107:2271897] 1
3 2020-04-29 18:00:27.838739+0800 GCDTest[56107:2271893] 2
4 2020-04-29 18:00:27.838759+0800 GCDTest[56107:2271894] 3
5 2020-04-29 18:00:27.838858+0800 GCDTest[56107:2271897] 4
6 2020-04-29 18:00:27.838860+0800 GCDTest[56107:2271893] 5
7 2020-04-29 18:00:27.838861+0800 GCDTest[56107:2271894] 6
8 2020-04-29 18:00:27.838898+0800 GCDTest[56107:2271775] 7
9 2020-04-29 18:00:27.838941+0800 GCDTest[56107:2271897] 8
10 2020-04-29 18:00:27.838951+0800 GCDTest[56107:2271893] 9
11 2020-04-29 18:00:27.839616+0800 GCDTest[56107:2271775] done

dispatch_resume/dispatch_suspend
当多个task在Dispatch Queue中执行时,有时不想再继续执行了,可以使用dispatch_suspend将队列挂起。再使用dispatch_resume恢复,值得注意的是,并不能取消已经开始的任务。

对于想取消的线程,并能监听线程的各种状态,可以使用NSOperation和NSOperationQueue,还能够设置*大并发量。

NSOperation、NSOperationQueue 是苹果提供给我们的一套多线程解决方案。实际上 NSOperation、NSOperationQueue 是基于 GCD更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。

可以添加任务依赖,方便控制执行顺序

可以设定操作执行的优先级

任务执行状态控制:isReady,isExecuting,isFinished,isCancelled

如果只是重写NSOperation的main方法,由底层控制变更任务执行及完成状态,以及任务退出
如果重写了NSOperation的start方法,自行控制任务状态
系统通过KVO的方式移除isFinished==YES的NSOperation

可以设置*大并发量
参考链接:https://www.jianshu.com/p/cbf759bdfd0f

dispatch TLS
线程TLS技术,Thread Local Storage(TLS)线程局部存储,目的很简单,将一块内存作为某个线程专有的存储,以key-value的形式进行读写,比如在非arm架构下,使用pthread提供的方法实现:

1  void* pthread_getspecific(pthread_key_t);
2  int pthread_setspecific(pthread_key_t , const void *);

GCD中也提供了相关的技术

1 #import <Foundation/Foundation.h>
2
3 static const void * const key1 = &key1;
4
5 int main(int argc, const char * argv[]) {
6     @autoreleasepool {
7         dispatch_queue_t queue1 = dispatch_queue_create(“com.ebebya.queue1”, NULL);
8         dispatch_queue_set_specific(queue1, key1, (void *)[@”ebebya” UTF8String], NULL);
9
10         dispatch_async(queue1, ^{
11             void *value = dispatch_get_specific(key1);
12             NSString *str = [[NSString alloc] initWithBytes:value length:7 encoding:4];
13             NSLog(@”%@”, str);
14         });
15     }
16     return 0;
17 }

但是是对于一个queue队列的上下文键值对,具体实现就不追究了。

滴答清单添加到 Apple Watch 表盘,不能自动更新数据变动

我把滴答清单添加到 Apple Watch 表盘上,只能*次进行数据自动更新,然后数据变动全部都要手动点进去才能更新,第三方 App 不能像自带的例如提醒事项、天气、日历一样数据变动自动反应到表盘上吗?

miyuki
    1

miyuki   1 天前 via iPhone

Things 好像也是?每天*次看都是“…”,点进去更新一下才有“Nothing to do”
eddie4607
    2

eddie4607   1 天前

我也有同样的问题。
MarlonFan
    3

MarlonFan   1 天前

我也有同样的问题。 +1
thx2u
    4

thx2u   1 天前 via iPhone

手表点好完成,手机上角标还在
leeyom
    5

leeyom   22 小时 44 分钟前

这个问题我咨询过,确实是这么回事,似乎 apple 对于表盘 app 上的软件有更新频率的限制
theolin
    6

theolin   13 小时 56 分钟前

watchOS 上的表盘组件也好,iOS14 上的小组件也好。它们的更新都不是实时的,只有系统能决定他们的更新时间和更新频率,app 自己决定不了。

 

iOS 更新至 14.4.2 后,自带输入法又抽风了,延迟好严重

下图里显示被触碰到时,其实我的手指已经是约前一秒的感觉。

RPReplay_Final1616787960

6 条回复    2021-03-27 09:27:45 +08:00
coldear
    1

coldear   5 小时 34 分钟前

每次更新都这样,过两天就好了
bclerdx
    2

bclerdx   3 小时 8 分钟前 via Android

没看出明显延迟。
xinbaqiu
    3

xinbaqiu   2 小时 47 分钟前 via iPhone   ❤️ 1

如果你是想要表示手指实际触碰跟显示触碰之间的延迟来说明新版本输入法抽风的话,这个图并不能说明?
starrystarry
    4

starrystarry   2 小时 36 分钟前

关掉 按键重复 试试
TmacV2
    5

TmacV2   2 小时 33 分钟前 via iPhone

对 ios 更新已经没有丁点兴趣了
thx2u
    6

thx2u   1 小时 22 分钟前 via iPhone

同事的 iPhone6p,一次都没更新过,如买来时流畅,且没遇到安全性问题、漏洞的网络攻击。
如果她每每更新,那么直接卡废了,变成年年换用户,更别提新功能、安不安全

现在入手 MacBook 值得吗? M1 芯片怎么说?

YzSama
    1

YzSama   1 小时 31 分钟前

不着急的话,可以等等。M1 用来开发的话,应该没啥问题吧。
fihserman123
    2

fihserman123   56 分钟前

我就是用来开发的 感觉没问题
kerrspace
    3

kerrspace   55 分钟前

我反而感觉可以用 window 本了因为 WSL 已经有图形界面了 原生态 Ubuntu 不比 MacOS 更接近生产环境。。。而且还能用显卡( CUDA etc )
kaka6
    4

kaka6   34 分钟前

从 thinkpad 使用多年,于上周换了 macbook air m1
*次用上 Mac 电脑,做为后端开发问题不大
稍威麻烦点就是好多软件要收费(都是贼贵),要去找破解
经过一周的折腾,基本上常用软件,开发环境,工具都配置全了
从 windows 到 Mac 本质上区别不大,所以很容易上手
但区别还是有的,在细节,Mac 的很多细节让你感觉:别扭 和 兴喜
别扭的是不习惯如 复制 粘贴的快捷键位置,还没搞习惯
兴喜太多了,用着用着会想:本该如此,太方便简洁了
换笔记本,从低配变高配,变化的可能是速度,容量
但从 window 到 Mac 我觉得变化是形为 和 思维模式,值得尝试
ichanne
    5

ichanne   24 分钟前

M1 直接接一个外接显示器,接多个要 trick 一下,还没弄
paullee
    6

paullee   19 分钟前 via iPhone

我的需求来说 m1 香爆了,我在灭门出黑苹果和 13 款 rmbp 了

求 windows 连接 Mac 工具推荐?

已经用过 teamviewer (被识别商用而不可用)
向日葵,因为是 MACmini 配置差,有时候连接失败,大概率是黑屏

除了这两种有没有其他软件推荐?谢谢~

13 条回复    2021-03-27 10:40:34 +08:00
Livid
    1

Livid   V2EX Moderator   19 小时 10 分钟前 via iPhone

VNC Viewer
lanceran
    2

lanceran   18 小时 48 分钟前

向日葵我用的 2014 款 mini 没问题,可能是你需要添加 SSD 了
wildcat007
    3

wildcat007   18 小时 37 分钟前

@Livid 谢谢,这个用过了。是不是因为我接入了一个电视机 60 吋造成的问题,分辨率太大了?
用的是 VNC,打开后 VNC 会卡死。
wildcat007
    4

wildcat007   18 小时 37 分钟前

@lanceran 参考 3 楼,会不会分辨率太大的问题?
smplesugar
    5

smplesugar   15 小时 50 分钟前

todesk
beginor
    6

beginor   14 小时 52 分钟前 via Android

Mac Mini 如果不连接显示器的话似乎无解, 只能 ssh 。

如果连接显示器的话就好多,todesk,anydesk,vnc viewer,nomachine,splash remote desktop 等

kid740246048
    7

kid740246048   14 小时 49 分钟前 via Android   ❤️ 1

remote desktop manager,官网是 https://remotedesktopmanager.com/ ,支持通过苹果的 ard 协议连接,效果还可以
ndliang
    8

ndliang   14 小时 38 分钟前

todesk 国产免费
yuange1975
    9

yuange1975   14 小时 8 分钟前

chrome remote desktop
gainsurier
    10

gainsurier   13 小时 58 分钟前 via iPhone

parallel access

stephen728
    11

stephen728   11 小时 1 分钟前 via iPhone

我从 win 用向日葵连我的黑果也很大概率连接后黑屏,这个时候切换一下向日葵菜单里的桌面模式从游戏模式切到办公模式就好了
wildcat007
    12

wildcat007   8 小时 38 分钟前

@kid740246048 哇~晚上试了下这个软件,真的是棒!
samin
    13

samin   9 分钟前

远程一般协议有 * 和 RDP

或者你直接用 TV 、向日葵、anydesktop 这类软件

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速