关于ios:iOS-view生命周期

2019/01/07 22:11 一、view生命周期 1、loadViewloadView办法负责创立UIViewController的view,每次拜访UIViewController的view,比方controller.view、self.view,且view为nil,就会调用loadView办法。 对于[super loadView]中的默认实现:(1)首先去查找与UIViewController相关联的xib文件,通过加载xib文件来创立UIViewController的view;(2)如果没有找到关联的xib文件,就会创立一个空白的UIView,而后赋值给UIViewController的view属性。 2、viewDidLoadloadView实现view创立后,会调用此办法,一般来说,咱们会在此处进行初始化的相干操作。 3、viewWillAppear试图行将呈现。 4、viewWillLayoutSubviews倡议布局试图在此处进行,这个办法会对所有试图进行真正的布局,包含self.view。 大部分状况下试图的布局代码写在viewDidLoad中没有问题,因为最终也是到这里进行布局操作的;然而多数状况下,这会导致一些奇怪的问题,尤其对于XIB而言,因为在 viewDidLoad 和 viewWillAppear 中,试图还是默认XIB的大小,在此办法中才会布局正确。 5、viewDidLayoutSubviews试图布局实现。 6、viewDidAppear试图曾经呈现。 7、viewWillDisappear试图行将隐没。 8、viewDidDisappear试图曾经隐没。 9、viewDidUnload这个比拟非凡。 设施的内存是无限的,如果应用程序占用的内存过多,零碎就会对应用程序收回内存正告,UIViewController就会收到didReceiveMemoryWarning音讯。 didReceiveMemoryWarning办法的默认实现是:如果以后UIViewController的view不在应用程序的视图层次结构(View Hierarchy)中,即view的superview为nil的时候,就会将view开释,并且调用viewDidUnload办法。 所以个别在开释资源,次要是开释界面元素相干的资源,将相干的实例都赋值为nil - (void)viewDidUnload { [super viewDidUnload]; self.name = nil; self.pwd = nil; }二、xib1、initWithCoder:将援用和内容文件从xib文件中加载到内存中 2、setValue:forKey:将outlet中制订的各个新属性 3、addTarget:action:forControlEvents:将xib中定制的手势交互等办法进行解决 4、bind:toObject:withKeyPath:options:连贯对象 5、awakeFromNib加载结束。

July 27, 2020 · 1 min · jiezi

关于ios:P3色域图片crash问题

问题形容:电脑上间接给手机装的包所有OK,然而App Store商店下载的包在9.0.2和9.2零碎上一点就闪退,要么进了利用后轻易点点就闪退. 起因排查:因为Release版的包敞开了日志,在控制台难以看到有用的信息.所以,只能去Xcode看iTunes统计的crash日志. 关上Xcode->Window->Organizer->Crashes,右边App Store抉择对应版本,期待日志下载实现. 找到crash的中央.能够看到crash的用户的零碎iOS9.2和型号iPhone 6s Plus. 选中crash那行,如果不是公有API的话左边会有一个箭头,点击箭头会跳转到代码中crash的中央,这样就能够找到问题所在了. 但如果是公有API就没有这箭头了,这时候点击左边的Open in Project,而后抉择对应的我的项目,这时候能够在我的项目中看到crash中央的堆栈调用; -[CUIStrucTuredThemeStore renditionWithKey:usingKeySignature:] 这是个苹果公有API,查寻材料发现此API报错指向图片色域问题. 解决方案:从iTunes下载我的项目的 ipa 并解压, 找到 Payload 中的 .app 文件, 显示包内容. 找到 Assets.car 文件, copy 到 Work 门路下,在终端执行命令 sudo xcrun --sdk iphoneos assetutil --info ./Assets.car > asset.json JerodMac:~ jerod$ cd /Users/jerod/Documents/Work JerodMac:Work jerod$ lsAssets.carJerodMac:Work jerod$ sudo xcrun --sdk iphoneos assetutil --info ./Assets.car > asset.jsonPassword:JerodMac:Work jerod$ 明码是电脑的登录明码. 执行实现后 Work 文件下会生成 asset.json 文件, 抉择文本形式或Sublime形式关上, 查问"DisplayGamut" : "P3" ...

July 27, 2020 · 1 min · jiezi

关于ios:ipa重签名

文章写于2016/07/13 19:34,搬家到思否。将一个ipa文件解压后,显示包内容,能够看到app文件目录下蕴含了这2个文件:_CodeSignature(ipa的签订文件)和embedded.mobileprovision(证书配置文件),另外还有一个本人配置的entitlements.plist受权文件,它们就是重签名的要害。 为了不便形容,先定义一些文件名(请依据本人的状况批改): 假如你的证书名为 myInhouse. mobileprovision 假如你的inhouse签订名为 iPhone Distribution: ABCD technology co., LTD. 假如你的ipa包名为 efg.ipa 一、查看证书信息、配置权限首先,查看myInhouse. mobileprovision的信息,在终端输出命令: security cms -D -i myInhouse.mobileprovision执行后输入信息中的内容,失去一个 XML 格局信息,找到Entitlements字段; 而后,创立一个 entitlements.plist 文件,依照上图中Entitlements的信息配置,如下图: 二、编写resign.sh脚本编写脚本,命名为 resign.sh #!/bin/shif ! ([ -f "$1" ]); thenecho ----- \"${1}\"文件不存在exitfiipaName=${1%.ipa}if [ "$ipaName" = "$1" ]; thenecho ----- \"${1}\"error 不是ipa文件exitfi## step 1 解压ipaunzip ${ipaName}.ipa## step 2 删除旧签名文件 rm -rf Payload/*.app/_CodeSignature/## step 3 拷贝证书配置和权限文件cp myInhouse.mobileprovision Payload/*.app/embedded.mobileprovisioncp entitlements.plist Payload/*.app/## step 4 重签名(/usr/bin/codesign -f -s "iPhone Distribution: ABCD technology co., LTD." --entitlements Payload/*.app/entitlements.plist Payload/*.app/) || { rm -rf Payload/ rm -rf __MACOSX/exit }## step 5 打包zip -r ${ipaName}_resign.ipa Payload/rm -rf Payload/rm -rf __MACOSX/三、签名脚本写完后,将 entitlements.plist 、myInhouse.mobileprovision 、resign.sh 、efg.ipa 放到同一目录ipaResign下, ...

July 27, 2020 · 1 min · jiezi

关于ios:ipa重签名

文章写于2016/07/13 19:34,搬家到思否。将一个ipa文件解压后,显示包内容,能够看到app文件目录下蕴含了这2个文件:_CodeSignature(ipa的签订文件)和embedded.mobileprovision(证书配置文件),另外还有一个本人配置的entitlements.plist受权文件,它们就是重签名的要害。 为了不便形容,先定义一些文件名(请依据本人的状况批改): 假如你的证书名为 myInhouse. mobileprovision 假如你的inhouse签订名为 iPhone Distribution: ABCD technology co., LTD. 假如你的ipa包名为 efg.ipa 一、查看证书信息、配置权限首先,查看myInhouse. mobileprovision的信息,在终端输出命令: security cms -D -i myInhouse.mobileprovision执行后输入信息中的内容,失去一个 XML 格局信息,找到Entitlements字段; 而后,创立一个 entitlements.plist 文件,依照上图中Entitlements的信息配置,如下图: 二、编写resign.sh脚本编写脚本,命名为 resign.sh #!/bin/shif ! ([ -f "$1" ]); thenecho ----- \"${1}\"文件不存在exitfiipaName=${1%.ipa}if [ "$ipaName" = "$1" ]; thenecho ----- \"${1}\"error 不是ipa文件exitfi## step 1 解压ipaunzip ${ipaName}.ipa## step 2 删除旧签名文件 rm -rf Payload/*.app/_CodeSignature/## step 3 拷贝证书配置和权限文件cp myInhouse.mobileprovision Payload/*.app/embedded.mobileprovisioncp entitlements.plist Payload/*.app/## step 4 重签名(/usr/bin/codesign -f -s "iPhone Distribution: ABCD technology co., LTD." --entitlements Payload/*.app/entitlements.plist Payload/*.app/) || { rm -rf Payload/ rm -rf __MACOSX/exit }## step 5 打包zip -r ${ipaName}_resign.ipa Payload/rm -rf Payload/rm -rf __MACOSX/三、签名脚本写完后,将 entitlements.plist 、myInhouse.mobileprovision 、resign.sh 、efg.ipa 放到同一目录ipaResign下, ...

July 27, 2020 · 1 min · jiezi

关于ios:移动App入侵与逆向破解技术-iOS篇

转载于2016/07/25,搬迁到思否。如果您有急躁看完这篇文章,您将懂得如何着手进行app的剖析、追踪、注入等实用的破解技术,另外,通过“入侵”,将帮忙您了解如何躲避常见的安全漏洞,文章纲要: 简略介绍ios二进制文件构造与入侵的原理介绍入侵罕用的工具和办法,包含pc端和手机端解说黑客技术中的动态剖析和动静分析法通过一个简略的实例,来介绍如何综合使用砸壳、寻找注入点、lldb近程调试、追踪、反汇编技术来进行黑客实战解说越狱破解补丁和不需越狱的破解补丁制作方法和差异黑客的素养敏锐的嗅觉 有时候通过一个函数名,一个类名,就能大抵的判断出它的作用,这就是嗅觉;功力已臻化境时,甚至能够应用第六感判断出一些注入点面对失败的勇气 破解有时候很耗时,和程序开发正好相同,它耗时不是耗在写代码上,而是耗在寻找注入点和逆向工程上,有可能你花了3天工夫去找程序的漏洞,然而最终的破解代码可能就2行,不到一分钟就搞定了;然而你也须要做好面对失败的筹备,如果路选错了,有可能你这3天齐全是在节约脑细胞洪荒之力 洪荒之力-即入侵过程中须要借助的各种工具,工欲善其事,必先利其器,工具都是前人智慧的结晶,能用工具解决的,绝不要手动去搞iOS黑客关键字iOS的入侵离不开越狱开发,所有的破解、入侵都是建设在越狱的根底上的,如果没有拿到零碎级权限,所有的想法都是空谈了,当然,市面上存在免越狱的破解补丁,然而它的开发过程,也是基于越狱环境的 tweak在iOS的黑客界,要做破解或越狱开发,就必须理解tweak,它是各种破解补丁的统称,在google上,如果你想搜寻一些越狱开发材料或者开源的破解补丁代码,它是最好的关键字。 iOS的tweak大抵分为两种: 第一种是在cydia上公布的,须要越狱能力装置,大部分是deb格局的安装包,iOS在越狱后,会默认装置一个名叫mobilesubstrate的动静库,它的作用是提供一个零碎级的入侵管道,所有的tweak都能够依赖它来进行开发,目前支流的开发工具有theos和iOSOpenDev,前者是采纳makefile的一个编译框架,后者提供了一套xcode我的项目模版,能够间接应用xcode开发可调试,然而这个我的项目曾经进行更新了,对高版本的xcode反对不好,大家酌情抉择(本文中的例子全副采纳theos)第二种是间接打包成ipa安装包,并应用本人的开发证书或者企业证书签名,不需越狱也能够装置,可间接放到本人的网站上,可实现在线装置;对于没有越狱的手机,因为权限的限度,咱们是没有方法写零碎级的tweak的,例如springboard的补丁是没法运行的,这种tweak大多是针对某个app,把指标app进行批改注入解决,再从新签名和公布,有点相似于windows软件的xxx破解版、xxx免注册版没有越狱的机器因为零碎中没有mobilesubstrate这个库,咱们有二个抉择,第一个是间接把这个库打包进ipa当中,应用它的api实现注入,第二个是间接批改汇编代码;第一个实用于较为简单的破解行为,而且越狱tweak代码能够复用,第二种实用于破解一些if…else…之类的条件语句 Mobilesubstrate上面的图展现的就是oc届驰名的method swizzling技术,他就是iOS的注入原理,相似于windows的钩子,所以咱们注入也称为hook Mobilesubstrate为了不便tweak开发,提供了三个重要的模块: MobileHooker 就是用来做下面所说的这件事的,它定义一系列的宏和函数,底层调用objc-runtime和fishhook来替换零碎或者指标利用的函数MobileLoader 用来在目标程序启动时依据规定把指定目录的第三方的动静库加载进去,第三方的动静库也就是咱们写的破解程序,他的原理上面会简略解说一下Safe mode 相似于windows的平安模式,比方咱们写的一些零碎级的hook代码产生crash时,mobilesubstrate会主动进入平安模式,平安模式下,会禁用所有的第三方动静库app注入原理下面讲到了mobileloader,他是怎么做到把第三方的lib注入进目标程序的呢?这个咱们要从二进制文件的构造说起,从上面的图来看,Mach-O文件的数据主体可分为三大部分,别离是头部(Header)、加载命令(Load commands)、和最终的数据(Data)。mobileloader会在目标程序启动时,会依据指定的规定查看指定目录是否存在第三方库,如果有,则会通过批改二进制的loadCommands,来把本人注入进所有的app当中,而后加载第三方库。 为了让大家看的更分明,上面我用machoview来关上一个实在的二进制文件给大家看看,能够看出,二进制当中所有援用到的动静库都放在Load commands段当中,所以,通过给这个段减少记录,就能够注入咱们本人写的动静库了 那么问题来了,在这里插入咱们本人的动静库有什么用?咱们本人写的代码没有执行的入口,咱们一样没发干坏事,嗯,祝贺你问到点子上了,咱们还须要一个"main"函数来执行咱们本人的代码,这个"main"函数在oc外面称为构造函数,只有在函数前申明 “attribute((constructor)) static” 即可,有了它咱们就能够施展想象力,进行偷天换日干点好事了: #import <CaptainHook/CaptainHook.h>CHDeclareClass(AnAppClass);CHMethod(1, void, AnAppClass, say, id, arg1){ NSString* tmp=@"Hello, iOS!"; CHSuper(1, AnAppClass, say, tmp);}__attribute__((constructor)) static void entry(){ NSLog(@"Hello, Ice And Fire!"); CHLoadLateClass(AnAppClass); CHClassHook(1, AnAppClass,say);} 到这里为止,咱们曾经晓得了怎么在目标程序注入本人的代码,那么咱们怎么晓得须要hook哪些办法?怎么找到关键点进行理论的破解呢?上面讲一下常见的app入侵分析方法 iOS逆向分析方法逆向剖析最罕用的有三种办法: 网络分析 通过剖析和篡改接口数据,能够无效的破解通过接口数据来管制客户端行为的app,罕用的抓包工具备Tcpdump, WireShark, Charles等,windows平台有fidller动态剖析 通过砸壳、反汇编、classdump头文件等技术来剖析app行为,通过这种形式能够无效的剖析出app实用的一些第三方库,甚至剖析出app的架构等内容,罕用的工具有dumpdecrypted(砸壳)、hopper disassembler(反汇编)、class_dump(导头文件)动态分析 有静就有动,万物都是相生相克的,动态分析指的是通过剖析app的运行时数据,来定位注入点或者获取要害数据,罕用的工具有cycript(运行时控制台)、 lldb+debugserver(近程断点调试)、logify(追踪)demo:微信抢红包插件下面讲了很多原理性的货色,置信大家曾经看的不耐烦了,上面咱们一起动点真格的,咱们从头开始,一步一步的做一个微信的主动抢红包插件,当然,网上可能曾经有相干的开源代码了,然而我这里要讲的是,这些代码是怎么得进去的,我么重点讲一讲剖析过程 工欲善其事,必先利其器一台越狱的手机,并装有以下软件 cycriptdumpdecrypteddebug serveropenssh一台苹果电脑,并装有以下软件 class_dumpTheosHopper Disassembler v3xcodeinsert_dylibpp助手寻找注入点砸壳首先咱们要做的就是把微信的壳砸掉,砸壳其实是为了把它的头文件classdump进去,因为从appstore下载的app二进制都是通过加密的,间接进行classdump操作是啥也看不出来的 ...

July 27, 2020 · 2 min · jiezi

关于ios:iOS封装framework

文章写于2016/04/08,搬家到此处第一篇 iOS封装Framework如果咱们心愿与他人共享某些函数,却又不违心裸露实现的细节,怎么办呢?这时候能够将咱们的代码封装成framework,对外提供接口而不裸露实现;不仅如此,将代码整合成framework还有很多其余的益处,这里就不一一列举。 上面就来看看如何打包成 framework 吧。 1、 创立工程 通过OS X > Framework&Library > Bundle 创立工程: 2、增加 Headers 在 Build Phases 中增加 Headers: Headers 开展后是这样的: 3、增加我的项目代码 将须要封装打包的文件退出我的项目中,这里最好用 copy 的形式退出: 4、合并头文件 为了不便他人应用 framework,最好创立一个头文件,并且在头文件下蕴含你所有想要公开的类,如此,当他人应用你的 framework 时只须要导入这一个头文件就能够了。 5、公开类 当代码退出了我的项目后,所有的 .h 文件都会主动呈现在 Headers 的 Project 上面,而后,咱们将须要公开的类拖到 Public 上面。 这里须要留神:Private 依然是公开的而不是公有的,不要被它的名字误导了,公有类保留在 Project 下就好。 6、更改一些设置: 6.1 info.plist > Bundle OS Type code = FMWK 6.2 Build Settings > Base SDK = Latest iOS,抉择最新的 ...

July 27, 2020 · 3 min · jiezi

关于ios:iOS个人证书与企业证书

文章写于2017.05.11,搬家到此处一、cer证书与mobileprovision文件开发iOS须要cer证书和mobileprovision形容文件 1、.cer证书 开发者的信赖证书(相当于你的身份证)。 2、.mobileprovision文件 蕴含了cer证书、利用包名(Bundle Identifier)、设施ID。 只有装置了这个文件Xcode能力调试(留神:这里的mobileprovision如果是distribution(上传AppStore的证书)那么它是不能在真机上测试的,只有上传到AppStore通过了审核能力从appstore下载安装到iOS设施外面)。 一般来讲只有有了下面的这证书文件,就能够在真机上调试了。 3、.p12 如果须要将证书给他人应用,能够从本地钥匙串里抉择相应的证书导出为.p12证书发给他人。p12蕴含了下面的.cer证书与.mobileprovision文件。 (留神developer的证书只能用于测试;distribution证书只能用来上传AppStore,没上线之前不能装置到iOS设施;inhouse证书须要设施信赖)。 二、iOS二种证书2.1 $99这种账号能够用来上传App Store提审并公布。 这种账号有集体和公司的区别: 集体账号:在上架App Store后,开发者间接显示申请人姓名,集体应用,每一种Apple产品,均有各类设施各100台测试权限。iPhone、iPad、Mac等。 公司账号:上架App Store的App开发者显示公司,公司账号下,能够增加多个测试子账号,反对Xcode在真机测试,然而子账号没有上传App Store权限。与集体账号权限相似,均有各类设施各100台测试机权限,iPhone、iPad、Mac等。 2.2 $299这种账号只能用于企业外部应用,测试设施有限,然而不能用来上传app store, 也就是常说的in-house证书(用这种证书打进去的包能在任何iOS设施上运行,不须要苹果的验证、签名)。 2.3 异同99美元的能够配置Ad-Hoc证书、公布证书(提审AppStore的证书); 299美元的能够配置Ad-Hoc证书、In-House证书,不能配置提审AppStore的证书。不要误会了这种账号即能上传AppStore又能In-House,这是两种不同账号的性能。 2.3.1 开发/调试证书(Development) 1、不能公布到Apple Store进行销售。 2、不须要Apple评审。 3、能够应用任何已知的公有API。 4、能够装置到任何苹果的设施上,无需任何签名和认证。 5、用户装置只须要一个ipa文件,无需证书和签名文件。 2.3.2 公布证书(Distribution) App Store - $99 公布到AppStore; 其实就是咱们常说的公布证书:distribution证书,用此证书打的包能够上传到AppStore提审,审核通过后就能够在AppStore下面公布,而后所有人就能下载安装应用了。 须要留神的是,在AppStore公布你的app之前,任何非越狱ios设施都不能装置此证书的包,只有在AppStore公布后,能力让所有的设施装置。 Ad Hoc - $99, $299 公布到指定设施; 公布进去的包须要通过iTunes装置。 100台,因为苹果的限度,在开发者网站上只能增加100台设施; In House - $299 公布到公司外部; 明确几个概念 1、企业版IDP:即iOS Development Enterprise Program。留神是$299/Year那种。 2、In House: 是只企业外部公布,仅限企业内部人员应用。 In-House形式特点 ...

July 27, 2020 · 1 min · jiezi

关于ios:iOS个人证书与企业证书

文章写于2017.05.11,搬家到此处一、cer证书与mobileprovision文件开发iOS须要cer证书和mobileprovision形容文件 1、.cer证书 开发者的信赖证书(相当于你的身份证)。 2、.mobileprovision文件 蕴含了cer证书、利用包名(Bundle Identifier)、设施ID。 只有装置了这个文件Xcode能力调试(留神:这里的mobileprovision如果是distribution(上传AppStore的证书)那么它是不能在真机上测试的,只有上传到AppStore通过了审核能力从appstore下载安装到iOS设施外面)。 一般来讲只有有了下面的这证书文件,就能够在真机上调试了。 3、.p12 如果须要将证书给他人应用,能够从本地钥匙串里抉择相应的证书导出为.p12证书发给他人。p12蕴含了下面的.cer证书与.mobileprovision文件。 (留神developer的证书只能用于测试;distribution证书只能用来上传AppStore,没上线之前不能装置到iOS设施;inhouse证书须要设施信赖)。 二、iOS二种证书2.1 $99这种账号能够用来上传App Store提审并公布。 这种账号有集体和公司的区别: 集体账号:在上架App Store后,开发者间接显示申请人姓名,集体应用,每一种Apple产品,均有各类设施各100台测试权限。iPhone、iPad、Mac等。 公司账号:上架App Store的App开发者显示公司,公司账号下,能够增加多个测试子账号,反对Xcode在真机测试,然而子账号没有上传App Store权限。与集体账号权限相似,均有各类设施各100台测试机权限,iPhone、iPad、Mac等。 2.2 $299这种账号只能用于企业外部应用,测试设施有限,然而不能用来上传app store, 也就是常说的in-house证书(用这种证书打进去的包能在任何iOS设施上运行,不须要苹果的验证、签名)。 2.3 异同99美元的能够配置Ad-Hoc证书、公布证书(提审AppStore的证书); 299美元的能够配置Ad-Hoc证书、In-House证书,不能配置提审AppStore的证书。不要误会了这种账号即能上传AppStore又能In-House,这是两种不同账号的性能。 2.3.1 开发/调试证书(Development) 1、不能公布到Apple Store进行销售。 2、不须要Apple评审。 3、能够应用任何已知的公有API。 4、能够装置到任何苹果的设施上,无需任何签名和认证。 5、用户装置只须要一个ipa文件,无需证书和签名文件。 2.3.2 公布证书(Distribution) App Store - $99 公布到AppStore; 其实就是咱们常说的公布证书:distribution证书,用此证书打的包能够上传到AppStore提审,审核通过后就能够在AppStore下面公布,而后所有人就能下载安装应用了。 须要留神的是,在AppStore公布你的app之前,任何非越狱ios设施都不能装置此证书的包,只有在AppStore公布后,能力让所有的设施装置。 Ad Hoc - $99, $299 公布到指定设施; 公布进去的包须要通过iTunes装置。 100台,因为苹果的限度,在开发者网站上只能增加100台设施; In House - $299 公布到公司外部; 明确几个概念 1、企业版IDP:即iOS Development Enterprise Program。留神是$299/Year那种。 2、In House: 是只企业外部公布,仅限企业内部人员应用。 In-House形式特点 ...

July 27, 2020 · 1 min · jiezi

关于ios:前端面试每日-31-第468天

明天的知识点 (2020.07.27) —— 第468天 (我也要出题)[html] 如何敞开HTML页面在IOS下的键盘首字母主动大写?[css] 在css中哪个属性会影响DOM读取文档流的程序?[js] 应用canvas画一个小球自由落体的成果[软技能] 个别与git服务器连贯有http/ssh等,你用的是哪种形式?为什么?《论语》,曾子曰:“吾日三省吾身”(我每天屡次检查本人)。前端面试每日3+1题,以面试题来驱动学习,每天提高一点!让致力成为一种习惯,让奋斗成为一种享受!置信 保持 的力量!!!欢送在 Issues 和敌人们一起探讨学习! 我的项目地址:前端面试每日3+1【举荐】欢送跟 jsliang 一起折腾前端,零碎整顿前端常识,目前正在折腾 LeetCode,打算买通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个Star, 同时欢送微信扫码关注 前端剑解 公众号,并退出 “前端学习每日3+1” 微信群互相交换(点击公众号的菜单:交换)。 学习不打烊,充电加油只为遇到更好的本人,365天无节假日,每天早上5点纯手工公布面试题(死磕本人,愉悦大家)。心愿大家在这虚夸的前端圈里,放弃沉着,保持每天花20分钟来学习与思考。在这变幻无穷,类库层出不穷的前端,倡议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢送大家到Issues交换,激励PR,感激Star,大家有啥好的倡议能够加我微信一起交换探讨!心愿大家每日去学习与思考,这才达到来这里的目标!!!(不要为了谁而来,要为本人而来!)交换探讨欢送大家前来探讨,如果感觉对你的学习有肯定的帮忙,欢送点个[Star]

July 27, 2020 · 1 min · jiezi

关于ios:iOS今日头条第3轮面试回忆

今日头条的iOS高级开发岗第三面,上面记录这次面试的回顾以作日后温习。一、自我介绍简略介绍一下你本人吧解析:简略介绍下本人的名字,教育背景,当初的工作,做过的我的项目二、自我介绍衍生的口头问题讲讲下你在你我的项目中做过的优化或者技术难点解析:介绍了本人封装的一个集picker,文本域的灵便开展的表视图。这个视图的数据源是json,怎么转成模型数组的?这个cell有哪些类型?展现的怎么辨别这些cell?这外面有用过复用机制吗?这些cell有实现过多重继承吗?题外话:这种问题最好各人本人找问题讲讲,不多,提前准备一个你我的项目中十分善于并相熟的点,即可。三、编程题:实现以下性能1) 编写一个自定义类:Person,父类为NSObject解析:头文件这样写 @interface Person:NSObject2) 该类有两个属性,内部只读的属性name,还有一个属性age解析:name的修饰符nonatomic,strong,readonly。age的修饰符nonatomic,copy。3) 为该类编写一个初始化办法 initWithName:(NSString *)nameStr,并根据该办法参数初始化name属性。解析:头文件申明该办法,实现文件实现该办法4) 如果两个Person类的name相等,则认为两个Person相等解析:重写isEqual,这外面波及到了哈希函数在iOS中的利用。四、由编程题衍生的口头题目4.1题目: 怎么实现内部只读的属性,让它不被内部篡改解析: 头文件用readonly润饰并申明该属性。失常状况下,属性默认是readwrite,可读写,如果咱们设置了只读属性,就表明不能应用setter办法。在.m文件中不能应用self.ivar = @"aa"; 只能应用实例变量_ivar = @"aa";,而外界想要批改只读属性的值,须要用到kvc赋值[object setValue:@"mm" forKey:@"ivar"];。实现文件外面申明公有属性,并在头文件在protocol外面规定该属性就能够了,内部通过protocol获取,这样还能够达到暗藏成员的成果。4.2题目: nonatomic是非原子操作符,为什么要这样,atomic为什么不行?有人说能atomic耗内存,你感觉呢?保读写平安吗,能保障线程平安吗?有的人说atomic并不能保障线程平安,你感觉他们的出发点是什么,你认同这个说法吗?对于为什么用nonatomic如果该对象无需思考多线程的状况,请退出这个属性润饰,这样会让编译器少生成一些互斥加锁代码,能够提高效率。 而atomic这个属性是为了保障程序在多线程状况下,编译器会主动生成一些互斥加锁代码,防止该变量的读写不同步问题。 atomic 和 nonatomic 的区别在于,零碎主动生成的 getter/setter 办法不一样。如果你本人写 getter/setter,那 atomic/nonatomic/retain/assign/copy 这些关键字只起提醒作用,写不写都一样。 对于atomic语nonatomic的实现苹果的官网文档 有解释,上面咱们举例子解释一下背地的原理。至于 nonatomic 的实现//@property(nonatomic, retain) UITextField *userName;//系统生成的代码如下:- (UITextField *) userName { return userName;}- (void) setUserName:(UITextField *)userName_ { [userName_ retain]; [userName release]; userName = userName_;}而 atomic 版本的要简单一些://@property(retain) UITextField *userName;//系统生成的代码如下:- (UITextField *) userName { UITextField *retval = nil; @synchronized(self) { retval = [[userName retain] autorelease]; } return retval;}- (void) setUserName:(UITextField *)userName_ { @synchronized(self) { [userName release]; userName = [userName_ retain]; }}简略来说,就是 atomic 会加一个锁来保障多线程的读写平安,并且援用计数会 +1,来向调用者保障这个对象会始终存在。如果不这样做,如有另一个线程调 setter,可能会呈现线程竞态,导致援用计数降到0,原来那个对象就开释掉了。 ...

July 24, 2020 · 1 min · jiezi

关于ios:厚积薄发开发期资源管理的策略选择

1)开发期资源管理的策略抉择 2)iOS14启动就Crash 3)IL2CPP加密:global-metadata.dat在iOS下的解密问题 4)如何实现可程序控制的3D动作 5)Unity Editor内Screen的Width和Height 这是第212篇UWA技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫10分钟,认真读完必有播种。 UWA 问答社区:answer.uwa4d.com UWA QQ群2:793972859(原群已满员) ResourceQ1:因为打包须要用AssetBundle,然而开发中用AssetBundle不太敌对,以上两种加载都会有各自的问题: Resources:须要放在Resources文件夹下,打包不好解决。 AssetDatabase:没有异步加载办法,开发中没方法模仿一些须要异步加载的状况。 目前我的项目用的Resources,打包机分了两个我的项目,打APK的我的项目阉割了Resources,写了独自版本治理更新命令,然而仍然挺麻烦。大部分公司都是用的AssetDatabase,请问是否有一些办法能够模仿异步加载? 另外以上两种办法都无奈模仿实在的卸载状况,导致组员不合理操作时,打AssetBundle后会有内存透露或者失落援用的状况,能够说一些大家公司开发时用的资源管理计划吗? A1:用AssetDatabase能够加一些随机延时模仿异步,资源加载的接口能够封装一下,做到依据配置来决定走AssetDatabase还是走AssetBundle。咱们打包机会把打好的AssetBundle主动提交到SVN,能够随时更新下来,在编辑器下测AssetBundle比拟不便。 另外:新的Addressable也能够试试看。 感激littlesome@UWA问答社区提供了答复 A2:据说过一个项目组做法是:平时开发应用Resources来加载;打AssetBundle或者正式包时,按某些规定依据Resources的目录主动生成一个新工程,这样就不必保护两个工程了。感激张迪@UWA问答社区提供了答复 A3:之前是协程模仿AssetDatabase下的异步,即LoadFromFileAsync。前面尝试过一种办法,就是应用独自的美术工程解决AssetBundle,而后程序工程不负责任何资源,只应用美术工程打包生成的AssetBundle。初听下来流程比较复杂,一点点小的改变即须要操作2个Unity工程。然而其长处也是十分多的。 代码上能够保留AssetDatabase的加载局部用于调试,当然能在日常开发中应用AssetBundle大部分时候能把AssetBundle的Bug裸露在Editor端,而不是上了真机才出问题。 感激cloud@UWA问答社区提供了答复 A4:以前是用Resources来加载,只不过会把资源放到Editor/Resources目录下来防止被打进包内。而后要公布的时候切换Flag,并读取Editor/Resources目录下资源进行打AssetBundle包。不过当初全副交给Addressables来治理了。 感激黄程@UWA问答社区提供了答复 iOSQ:在iOS 14公布之后,就呈现闪退问题了。和机型没关,只有是iOS 14就必闪退的那种,iOS 13就失常。用的Unity版本是2018.2.3。求教有人遇到过吗? A:咱们iOS14也出了情况,有两个体现: 启动就闪退,多起几次能够过来。启动后到某个阶段之间卡死(必卡跳不过)。XCode里看,始终是GfxDriver报错,咱们渠道方发现,XCode里【BuildSetting - Packaging - Product Name】不能含有中文,有中文就出这个问题,改掉就好了。 根本原因尚不明确,集体猜想Product Name会影响Header Folder Path,可能是代码加载门路中呈现中文会出问题(相似晚期Unity的情况)。心愿对你有帮忙。 感激Walker@UWA问答社区提供了答复 iOSQ1:为了加大破解难度,须要对global-metadata.dat文件进行加密。 实现形式是: 1. 加密在导出Android和Xcode工程后进行,对global-metadata.dat按字节加密。 2. 批改: Android:\Editor\Data\il2cpp\libil2cpp\vm\MetadataLoader.cpp Mac:Unity.app\Contents\il2cpp\libil2cpp\vm\MetadataLoader.cpp 文件中的LoadMetadataFile函数,对从文件中读取进去的内容按字节解密。 当初呈现的问题是:在Android上没有问题,能够失常加密和运行游戏。然而在Mac上,貌似解密函数没有失效,导致启动游戏解体。 求教一下各位大佬:在Mac上,global-metadata.dat的读取是不是不是通过这个函数。我看到Mac上Unity装置目录还有一个PlaybackEngines文件夹,外面也有IL2CPP相干文件,例如MetadataLoader.h,但这个文件是只读的,无奈批改,而且也没有找到MetadataLoader.cpp。Mac上解密不失效和这个文件无关吗? A:iOS上是间接链接预编译好的PlaybackEngines\iOSSupport\Trampoline\Libraries\libil2cpp.a 可能须要本人把.a从工程里移除,把IL2CPP源码引入到工程里。Q2:工程是指iOS Support/Tramponline文件夹下的Xcode工程吗?要把Unity.app\Contents\il2cpp\libil2cpp中的文件全副退出到这个工程外面是吗? A:是领导出的我的项目工程。具体哪些文件可能须要本人试试了。能够在Windows上导个IL2CPP的VS工程对照一下文件和编译参数。Q3:咱们最近遇到这个iOS加密Metadata的问题,请问最初有找到解决方案吗?https://forum.unity.com/threa... 看这个帖子,仿佛是须要Unity源码才能够? A:IL2CPP的代码间接拖到XCode工程里应该就能够了。感激littlesome@UWA问答社区提供了答复 AnimationQ:咱们的需要是心愿用程序实现灵便的拍掌动作,如下图: 两头一个大模型,左右两手,两手掌要做拍掌动作,蓝色点都可作为拍掌点,就是说要让程序控制拍到哪里。目前想到的计划是: 1. 做很多个拍掌动画,而后在Blend Tree里用二维混合,但那样不够准确。 2. 用Final IK,管制两手掌静止,但那样做的动作不天然。 ...

July 24, 2020 · 1 min · jiezi

关于ios:Apple-Widget下一个顶级流量入口

0x00 前言2020 年 6 月 22 日,苹果召开了第一次线上的开发者大会 - WWDC20。这堪称是一次能够载入史册的发布会,发表了 ARM 架构 Mac 芯片、软硬件的生态大对立、iOS 14 零碎界面大改等一系列激动人心的音讯。 当然,最让我感兴趣的就是让 iOS 界面大改的 Widget 了。过来几年,iOS 的桌面交互体验堪称是一言难尽,Widget 的退出无疑是一次比拟大的破局。在看发布会的时候,我的脑海里就浮现出一个问题:“这会是下一个互联网公司竞争的流量入口吗?” 先不抛论断,让咱们先看一下 WWDC20 介绍了哪些对于 Widget 的新货色。 ( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...   本篇内容来自于阿里巴巴淘系技术部,高级无线开发工程师柘剑。 更多精彩内容可关注【淘系技术】公众号。) 0x01 什么是 Widget?Widget 不是一个小型的 App,它是一种新的桌面内容展示模式,次要是用于补救主应用程序无奈及时展现用户所关怀的数据。如下图所示: 一个优良的 Widget 须要有三个特点:简单明了(Glanceable)、失当展现(Relevant)、个性化定制(Personalized) 简单明了(Glanceable)Widget 不是一个小型的 App,这句话被重复提起。个别用户每天进入主屏幕的次数超过 90 次,但停留的总时长不过几分钟。通常来说用户只会在主屏幕上停留片刻工夫,就会跳转到其余中央,所以并不需要任何简单的交互设计来加强 Widget 的作用,也不须要简单的款式来丰盛 Widget 的内容,简单明了的内容才是 Widget 的要害。 和安卓的 Widget 不太一样,苹果设计的 Widget 并不反对任何交互行为,也不倡议大家设计过于简单的款式来出现内容,这也十分合乎苹果对于主屏幕的改良始终放弃克服的特点。 失当展现(Relevant)苹果冀望 Widget 能够和正在执行或者思考的事件严密的联合。比方,早上起床,用户最关怀天气怎么样,Widget 能够展现一下天气情况;起床后,用户就要理解一下一天的行程,Widget 能够展现一下 Reminders 中的内容;等到一天忙完了,筹备睡觉的时候,能够用 Widget 关上音乐略微放松一下。为此,苹果零碎提供了一个叫智能叠放(Smart Stacks)的性能,智能叠放是一个 Widgets 的汇合。零碎会依据每个人的习惯,借助端智能的能力,主动的显示精确的 Widget 在最顶部。 ...

July 23, 2020 · 3 min · jiezi

关于ios:Metal新特性大幅度提升iOS端性能

前言Metal 是一个和 OpenGL ES 相似的面向底层的图形编程接口,通过应用相干的 api 能够间接操作 GPU ,最早在 2014 年的 WWDC 的时候公布。Metal 是 iOS 平台独有的,意味着它不能像 OpenGL ES 那样反对跨平台,然而它能最大的开掘苹果挪动设施的 GPU 能力,进行简单的运算,像 Unity 等游戏引擎都通过 Metal 对 3D 能力进行了优化, App Store 还有相应的使用 Metal 技术的游戏专题。 阿里巴巴淘系技术部的闲鱼团队是比拟早在客户端侧抉择Flutter计划的技术团队,以后的闲鱼工程里也是一个较为简单的Native-Flutter混合工程。作为一个2C的利用,性能和用户体验始终是闲鱼技术团队在开发中比拟关注的点。而Metal这样的间接操作GPU的底层接口无疑会给闲鱼技术团队突破性能瓶颈提供一些新的思路。 上面会具体论述一下这次大会Metal相干的新个性,以及对于闲鱼技术和整个淘系技术来说,这些新个性带来了哪些技术启发与思考。 ( WWDC 2020精彩内容思否专栏:https://segmentfault.com/blog...   本篇内容来自于阿里巴巴淘系技术部,无线开发工程师岑彧。 更多精彩内容可关注【淘系技术】公众号。) Metal相干新个性1.Harness Apple GPUs with Metal这一章其实次要介绍的是Apple GPU的在图形渲染上的原理和工作流,是一些比拟底层的硬件原理。当咱们应用Metal进行App或者是游戏的构建的时候,Metal会利用GPU的tile-based deferred rendering (TBDR)架构给利用和游戏带来十分可观的性能晋升。这一章次要就是介绍GPU的的架构和能力,以及TBDR架构进行图像渲染的原理和流程。总之就是号召开发者们应用Metal来构建利用和游戏。因为这个session没有波及到下层的软件开发,就不对视频的具体内容进行赘述了。详情可见:Harness Apple GPUs with Metal 2.Optimize Metal apps and games with GPU counters这一章次要介绍了Xcode中的GPU性能剖析工具Instrument,这个工具当初曾经反对了GPU的性能剖析。而后从多个方面剖析了GPU的性能瓶颈,以及性能瓶颈呈现时的优化点。总体来说就是通过性能剖析工具来优化咱们的App或者游戏,让整个画面更加晦涩。整个章节次要分为五个局部: 1.总体介绍这个环节次要是疾速回顾了一下Apple的GPU的架构和渲染流程。而后因为很多渲染工作都须要在不同的硬件单元上进行,例如ALU和TPU。他们对不同的吞吐量有着不同的度量。有很多GPU的性能指标须要被思考,所以推出了GPU性能计数器。这个计数器可能测量到GPU的利用率,过高和过低都会造成咱们的渲染性能瓶颈。对于计数器的具体应用,参考官网的video成果会更好:Optimize Metal apps and games with GPU counters(6:37~9:57),次要应用了Instrument工具,对于工具的全面具体的应用能够参考WWDC19的session videoGetting Started with Instruments ...

July 20, 2020 · 1 min · jiezi

关于ios:苹果开发者账号申请政府组织类2020

博客搬迁至此2020-01-15一、筹备资料1. 申请机构工作人员的根本信息(该工作人员作为申请人或者被授权人,必须是组织机构中的工作人员):姓名,工作职位(英文),电子邮箱,手机号码,生日。 2. 证实人或者授权人的根本信息(为组织机构中,有权威代表组织机构,个别填写科长或者副科长):姓名,工作职位(英文),电子邮箱,手机号码,生日。 3. 申请机构的根本信息:机构名称(英文),地址(英文),官网网址,联系电话。 4. 反对VISA或者万事达的信用卡(这里因为波及平安码等问题,付费问题也能够由客户自行付费) 二、注册Apple ID如果您曾经领有Apple ID,跳过此步骤。 1. 注册地址: https://appleid.apple.com/account#!&page=create 填写好信息,确认无误后点击“持续; 舒适提醒:请记好明码和窃密问题。 2. 填入发送到邮箱的验证码,而后“持续”; 3. 填入发送到手机的验证码,而后“持续”; 4. Apple ID 注册实现 5. 为Apple ID开启双重认证 任何 Apple ID 帐户只有至多领有一台装有最新版 iOS、iPadOS 或者 macOS 的设施,都能够应用双重认证。进一步理解。 您能够在 iPhone、iPad 或 iPod touch 上登录Apple ID后依照以下步骤来开启双重认证。 a) 在“设置”中开启双重认证 如果应用的是 iOS 10.3 或更高版本: 返回“设置”>“[您的姓名]”>“明码与安全性”。 轻点“开启双重认证”。 轻点“持续”。 如果应用的是 iOS 10.2 或更低版本: 返回“设置”>“iCloud”。 轻点您的 Apple ID>“明码与安全性”。 轻点“开启双重认证”。 轻点“持续”。 零碎可能会要求您答复 Apple ID 平安提醒问题。 ...

July 19, 2020 · 2 min · jiezi

iOS-涨薪-Run-Loop-面试题

Run Loop 运行循环 app 程序只有不停地运行, 能力一直响应用户的操作Run Loop 两大性能: 睡眠中,期待音讯解决音讯从睡眠中 -> 解决音讯, 须要一个唤醒的过程 1、 讲讲 RunLoop, 我的项目中有用到吗? RunLoop 的根本作用: 放弃程序的继续运行 节俭 CPU 的资源,进步程序的性能 ( 没有事件,就请休眠,不要功耗。有事件,就解决) 2、 RunLoop 外部实现逻辑? Core Foundation 中对于 RunLoop 的 5 个类:CFRunLoopRef CFRunLoopModeRef CFRunLoopSourceRef CFRunLoopTimerRef CFRunLoopObserverRef __CFRunLoop 的数据结构struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked for accessing mode list */ __CFPort _wakeUpPort; // used for CFRunLoopWakeUp Boolean _unused; volatile _per_run_data *_perRunData; // reset for runs of the run loop pthread_t _pthread; uint32_t _winthread; CFMutableSetRef _commonModes; CFMutableSetRef _commonModeItems; CFRunLoopModeRef _currentMode; // 这里有一个汇合 CFMutableSetRef _modes; struct _block_item *_blocks_head; struct _block_item *_blocks_tail; CFAbsoluteTime _runTime; CFAbsoluteTime _sleepTime; CFTypeRef _counterpart;};3、 RunLoop 和线程的关系? ...

July 15, 2020 · 2 min · jiezi

LinkedIn-秘密收集用户剪贴板信息或面临集体诉讼

技术编辑:芒果果丨发自 思否编辑部SegmentFault 思否报道丨公众号:SegmentFault 互联网时代,智能手机中简直所有的应用程序都会收集用户的个人信息。当初咱们要防的除了应用程序自身,居然还有剪贴板。 尽管有些 App 的拜访权限的并不是很必要,但在收集用户的信息前它起码进行了告知,容许用户自行抉择。但最近却频频有利用机密读取用户剪贴板的状况被爆出。 近日,微软公司的 LinkedIn 就因为读取用户剪贴板信息并转移敏感内容的事件被 iPhone 用户告上了法庭。根据加州法律,该诉讼将以涉嫌违反法律或社会规为由,成为个体诉讼。 应用程序频频被爆收集剪贴板信息几天前刚刚有降级了 iOS 14 的用户发现手机内的 TikTok 会“拜访”剪贴板的内容。对此,TikTok 的所属公司字节跳动也做出了解释,示意是解决违规信息的性能产生了误触,并已删除了此性能。此事刚刚平息,LinkedIn 就被爆出了雷同状况。 自 6 月 23 日苹果在 WWDC 上公布了 iOS 14 后,进行了系统升级的用户就能够在信息被其余利用读取时收到正告。上次 TikTok 被发现读取用户剪贴板信息也是因为大量用户发现了零碎收回的“拜访正告”。 苹果 iOS 14 的开发人员和测试人员发现,LinkedIn 在 iPhone 和 iPad 上“机密地”大量读取了用户的剪贴板。 被纽约的用户起诉后,LinkedIn 的一位高管在 Twitter 上示意,“公司已公布了新版本的应用程序”。 LinkedIn 称已更新应用程序iOS 零碎通常容许用户在苹果的一个设施上复制文本、图像、照片和视频,而后将内容粘贴到另一个苹果设施上。但 LinkedIn 是在未告诉用户的状况下读取了剪贴板信息。 依据投诉,LinkedIn 不仅在监督用户,而且还在监督其左近的计算机和其余设施,并且始终在躲避苹果的 Universal Clipboard(iOS 和 Mac 设施之间的通用性剪贴板)。 目前,除了一位高管在 Twitter 上示意已更新了应用程序外,LinkedIn 尚未对此事作出回应。 装置一个新的 App 时,会跳出是否容许拜访通讯录、相册、地位等内容的询问,大多数状况下咱们都会抉择容许,因为“不容许”很可能会导致应用程序无奈应用。 但越是个人信息被大程度公开的互联网时代,越要增强隐衷爱护,这须要应用程序开发者和用户集体独特的致力。 技术能力不体现在通过何种伎俩收集了更多用户信息,而在于其性能失去用户的宽泛认可。 ...

July 13, 2020 · 1 min · jiezi

iOS-Rendering-渲染解析问题解答

1、 CPU 和 GPU 的设计目标别离是什么? cpu是用于简单逻辑计算和管制 领有四个局部 control cache alu dram 其中cache占比比拟大 串行计算 低延时设计。 gpu 图形处理核心 能够进行多线程 高并发简略计算 大吞吐量 2、 CPU 和 GPU 哪个的 Cache、ALU、Control unit 的比例更高? cpu cache高 gpu alu 比例高 计算单元 Arithmetic Logic Unit 3、 计算机图像渲染流水线的大抵流程是什么? 图元-顶点着色器-线条着色器-几何着色器-光栅化-片段着色器-测试与混合 图像在利用中被解决的阶段,此时还处于 CPU 负责的期间。在这个阶段利用可能会对图像进行一系列的操作或者扭转,最终将新的图像信息传给下一阶段。这部分信息被叫做图元(primitives),通常是三角形、线段、顶点等 4、 Framebuffer 帧缓冲器的作用是什么? 存储通过gpu解决后的bitmap 5、 Screen Tearing 屏幕撕裂是怎么造成的? 当显示器电子束从新开始下一帧的扫描时帧缓冲器里的bitmap还没有ready此时扫描进去的是上一帧的内容而后帧处理器的bitmap被替换也就是扫了一半就变成了新的bitmap这样展现的内容就是上一帧和以后帧的拼接 6、 如何解决屏幕撕裂的问题? vsync 垂直同步信号,每次电子束完结,当晚( woqu )屏幕的扫描会发送一个vsync给frame buffer 而后frame buffer才会读取新的frame 7、 掉帧是怎么产生的? 电子束完结以后frame的display然而 gpu还没有解决完 没有新的bitmap 所以还会展现之前的frame ...

July 13, 2020 · 1 min · jiezi

跳槽季iOS开发救救自己别再这样写简历了

 下篇:‘跳槽季’ iOS开发者,写一份胜利的简历?金三银四跳槽季,转瞬已渐入序幕,我作为部门的面试官,在此期间也播种了不少简历。但惋惜的是,收到的简历数量虽多,但令人中意的却是凤毛菱角,一些应聘者倒不是因为本身能力有余而无奈进入面试环节,而是简历自身就没有很好的展现出本人的能力,因而与面试的时机擦肩而过。 为了防止相似的「喜剧」重复呈现,我分享一些我在简历制作上的一些心得和倡议,心愿能帮忙到有需要的读者在下次的求职中更加顺利。 在上面的篇幅中,我将讲述我最看重简历的三个局部,心愿能对各位读者有所启发,这三个局部别离是:  1.技术能力;2.我的项目经验;3.整体印象;就我的教训而言,可能将这三局部依照肯定准则写好的简历,是没有理由无奈取得一次面试机会的,那么话不多说,让咱们开始吧 ????。 1. 技术能力 =========== 通常,「技术能力」这个局部将紧接着您的个人简介之后,放在简历的外围版面。这样设计是有情理的,因为它可能帮忙雇主更快的判断您的技能是否与需要相吻合。 因而在制作这一部分内容时,您应该思考以下两点: (1)写什么?应聘者在技术能力的形容上通常会犯两个谬误:要么无用的货色写的太多,要么有用的货色写的太少。这里的多和少是绝对于「雇主的招聘需要」而言的。 我倡议每个应聘者在撰写简历的这部分时,都可能精心设计所需展现的技能,将本人熟练掌握的技能中与雇主需要重合的局部放在醒目的地位,如果居然还有充裕,那当然能够自豪的在其后展现。 我倡议每个应聘者在撰写简历的这部分时,都可能精心设计所需展现的技能,将本人熟练掌握的技能中与雇主需要重合的局部放在醒目的地位,如果居然还有充裕,那当然能够自豪的在其后展现。 (2)怎么写?当咱们晓得该写什么技能之后,咱们还须要晓得如何失当的形容这些技能,通常咱们会以:「理解,相熟,熟练掌握,精通」这几个形容词来形容技能的熟练程度,让我从面试官的角度来与您分享一下我认为这几个词背地的含意: 1.理解:示意您据说过这个概念,甚至理解与此概念无关的基本原理; 2.相熟:示意您通过 Demo 的模式实际过某个技术,或做过一两个与该技术无关的我的项目,但不足积淀; 3.熟练掌握:示意您在工业级环境下,通过数个我的项目的实际曾经把握了某种技术的外围原理,并可能灵便的利用在开发中; 精通:示意您通过很屡次的我的项目实际和潜心研究,曾经对某种技术的原理和利用把握到近乎尽如人意的水平; 您应该意识到您须要主观,诚恳地评判本人的技术水平,既不要蓄意的夸张,也不应该不可一世。在撰写该局部内容时,我建议您依照技能的熟练程度自高向低的排列,同时对于雇主明确示意须要的技能给予更高的优先级。 2. 我的项目经验讲完了技术能力,接下来将与您分享简历中最重要的局部 -- 「我的项目经验」。如果一份简历满分是 100 分,我的项目经验所占的分数应该是 50 分以上。所以务必请您分外注意。 让我形容一下我常常看到的一类形容: 我在该我的项目中实现了 XXX,YYY 需要,使用了 a,b,c 技术。我至今不明确,这种不足意义的形容为什么会如此经久不衰的呈现在各式各样的简历中,又为什么有这么多求职者对于这个模版的使用如此的乐此不疲。 这种形容形式的弊病在于,它除了通知我求职者的确有在工作之外,再没有其余有用的信息。 3. 简历印象局部 ============= 说完了技能和我的项目经验,最初让咱们谈谈撰写简历时须要恪守的一些准则。当一份简历投递雇主手中时,雇主通常会大略看一下这个简历,凭教训和直觉来判断是否持续浏览这份简历,而接下来我想与您分享的,便是我认为一份好简历应该具备的「好滋味」。 (1)撰写简历三大准则:清晰,简短,必要;正如题目所出现的,一份好简历应该满足以下三个特色: 1.清晰:这表明简历的内容应该是没有歧义,易于了解的,同时简历整体还要富裕逻辑; 2.简短:无论是生存还是工作中,咱们都须要领有一种「抓住重点」的能力,因而优良的求职者应该尽可能在简历中就展示这一点,而展示的形式就是,尽量写出不超过一页的简历,同时让它充斥引诱; 3.必要:招聘自身是一个互相匹配的过程,彼此展现必要的信息,可能帮忙彼此最大化的节约工夫,晋升效率。确保简历中呈现的内容都是雇主冀望理解的很容易就能赢得雇主的好感。 心愿您能在了解这三准则后从新扫视并优化您的简历,确保十拿九稳后,咱们就能够进入下一个重要的环节:简历投放。没错,这里我也有话要说。 (2)为什么您应该进行海投?我的最初一个倡议是:不要海投,要对症下药。 我当然了解面对求职压力,海投所耗费的老本及其低廉,但请留神,绝对的,海投带来的收益也近乎微不足道(更别提海投失败更容易给人带来挫败感,使人陷入一种负面情绪的恶性循环)。 其实「海投」和「精准投放」之间的差距并没有特地迥异,有时候只须要您一点点额定的致力,就能带来微小的收益。 我建议您将本人的所有信息先整合在一个文档内,而后每天抉择 10 家您向往的雇主企业,仔细阅读对方的招聘需要,并依据对方的招聘需要在本人的文档中摘出与之匹配的局部组合在一起。 之后就能够痛快的投递进来了。猜猜看接下来会产生什么?因为您的技能形容完满符合了雇主的须要,并且我的项目经验的形容因为使用了 STAR 法令,雇主可能更充沛的理解到您各方面的能力。 毫无疑问的,您将大大晋升您进入面试环节的几率! 这可是胜利的第一步! 4. 结尾 ========= 至此,文章终于到了序幕。总结一下,咱们议论了简历制作过程中须要留神的以下三个局部,并别离给出了一些倡议: 1.技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;2.我的项目经验:只写明星我的项目,形容遵循 STAR 法令;3.简历印象:简历遵循三大准则:清晰,简短,必要,要对症下药,不要海投;心愿我所分享的教训能对您有所帮忙,也心愿您终能如愿以偿进入心仪的企业工作。 感谢您读到这里,真是不容易! 5.结交人脉作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这是一个我的iOS交换群:1001906160 ,进群明码000,不论你是小白还是大牛欢送入驻 ,分享BAT,阿里面试题、面试教训,探讨技术, 大家一起交流学习成长!

July 10, 2020 · 1 min · jiezi

嘿iOS开发你准备好何时跳槽了吗

序言 我置信很多人都在说,iOS行业不好了,iOS当初行情越来越难了,就业的人比找工作的人还要多。就业即相当于转行,跳槽即相当于升高本人的身价。那么做iOS开发的你,你是否在时刻筹备着跳槽或者转行了。 咱们先看一下当初iOS行业,iOS程序员在现在竞争强烈的市场环境下,你本人还值多少钱,上面是按年限,按要求提出的工作及薪资待遇。 一年以内,一至三年,本科: iOS市场,薪资待遇 iOS市场,薪资待遇 iOS市场,薪资待遇 那么你处于哪一个阶段!,你拿的薪资待遇怎么样,你的工作怎么样,是不是天天加班,有改不完的bug,没有工夫陪本人的小孩,爱人,家人。面对这样的一个现实情况,你本人是否还在保持,保持本人的岗位,是否去想过转行,跳槽。面对现实的生存,就业的你,或者想跳槽的你,你真的做好筹备了吗? 接下来小编会来浅谈一下iOS开发中有哪些方向和职业规划,同时小编也欢送大家退出小编的iOS交换群761407670,明码‘000‘,群里会提供相干面试材料,书籍欢送大家入驻!iOS开发的你正处于哪一个技能阶段和年限,学好这些,把握这些,你会在如此定义你本人方向和职业规划: ** 1、架构师 2、平安攻防 3、逆向编程 4、iOS进阶 5、底层开发 6、swift4.0开发** 小编为大家整顿一下,不论做iOS开发几年的都能够看一下,畅通与总结这几年本人的ios编程之路,程序员之路,兴许是辞别你的编程之路,兴许是再次点燃你心田的星星之火。 一、iOS架构师应该理解把握的 iOS架构师应该去理解把握“UML建模”、“软件工程架构与设计模式”、“第三方库” UML建模 软件工程架构与设计模式 第三方库 二、iOS平安攻防应该理解与把握的 iOS平安攻防在“攻”与“防”中会有哪些了,须要懂哪些? ** 1、 “攻”应该包含这些在类** ** (1)iOS逆向工程介绍** ** (2)逆向工具与实践** ** (3)我的项目实际** ** (4)构建防护** OS逆向工程介绍 逆向工具与实践 我的项目实际,构建防护 2“防”应该包含这些在类 **(1)加密与取证**** (2)反取证** ** (3)运行时库平安** 加密与取证 反取证,运行时库平安 三、iOS进阶学习应该须要理解并把握的 **(1)多线程与网络进阶**** (2)iOS底层进阶** ** (3)iOS主动打包** 多线程 ...

July 9, 2020 · 1 min · jiezi

我的-2020-iOS-BAT面试心得Bigo字节快手伴鱼百度微博等

ps:后面按照自己面试的时间顺序来写,记录的面试题是我印象比较深刻的,并不一定很全,暂时先提供面试题,后面考虑给出相应的题解。面试我面试了大大小小的各种公司,BAT、bigo、字节、快手、伴鱼等,因为一些原因,也拒面了一些公司,拿了几家的offer。 伴鱼伴鱼是我准备后参加的第一轮面试,有很多自己准备得不是很全,也没有完全进入面试状态,面试结果不是很好,一面就挂了。 一面算法题:判断平衡二叉树(easy)代码阅读题:(问输出)TestObject *object1 = [[TestObject alloc] init];__block TestObject *object2 = [[TestObject alloc] init];object1.name = @"Mike";object2.name = @"Sean";__block int vi = 1;void (^handler)(NSString *) = ^(NSString *name) { object1.name = name; object2.name = name; vi = 2;}handler(@"Lucy");NSLog(object1.name);NSLog(object2.name);NSLog(@"%i", vi);引申: 如果__block int vi = 1; 这句改成int vi = 1会怎样,为什么代码中的block是什么block,为什么 weak的实现原理weak弱引用表是可变的么还是不可变的weak是在什么时候置nil的,如果同时有很多对象对性能影响大怎么办UIView 和 CALayer的关系和区别UIView 和 CALayer在动画上的区别frame和bounds在什么情况下是不相等的bounds x,y 一定是0,0么,为什么bounds 改成 (50, 50, width, height)会发生什么,view本身,子View?5858我面了很多次,一开始面的基础研发部门,后来给我转到了企业工具研发,中间时间拖得有点长,直接拒面了。 一面说下你在开发过程中遇到过的内存泄漏NSTimer 怎么处理内存泄漏Delegate什么情况下会出现内存泄漏,怎么解决Delegate和Notification的区别多线程相关 iOS中有哪些多线程技术如果有两个同步任务嵌套会怎样常见的锁,为什么要加锁C依赖AB任务执行完才能执行,你怎么设计读写锁底层怎么实现JavaScriptCore相关 什么是JavaScriptCore,JS和Native是怎么进行通信的你知道hybrid么,说说你平常怎么使用的(因为没怎么接触过直接说的不会)后面就是聊天了,中间穿插问了下动态库和静态库的却别二面(终面)58这个部门的面试就两轮,二面是群面(几个人轮流面你),第一次接触这种面试形式,压力还是有点的。 对我的项目表感兴趣,前面聊了不少项目的内容,问了下项目的背景,做了啥以及有哪些收益了解业内性能优化是怎么做的么你项目中是怎么做性能优化的ReactNative相关 RN的原理RN和flutter的区别你知道RN拆包么,RN为什么要拆包JS是单线程的是怎么和native多线程进行交互的(这个问题有点奇葩)JS和native通信的数据结构是什么你们公司对于线上JSError做了哪些事情是怎么处理的你有什么想问的么一个创业公司这个创业公司全程都是在聊天,后面问了些和iOS没多大关系的问题,然后就发了口头offer。 聊天:在公司中学到了啥,为啥要来北京等有一个10个G的文件里面每一行都有数字,对这些数字进行排序(两种方法)怎么将彩色的图片专程黑白的Web渲染和Native渲染有什么异同点拼多多拼多多应该是自己面的一个相对较大的公司,面试过程中和面试官有了点小分歧,后面问我源码在哪个文件哪一行,后面问得问题也基本上是我之前没怎么接触过的。 ...

July 7, 2020 · 1 min · jiezi

App-Clips

该文章属于<简书 — 刘小壮>原创,转载请注明:<简书 — 刘小壮> 前两天leader让我调研一下App Clips,我简单调研了一下,这是我调研的一些总结,大家可以看看,有问题欢迎评论区讨论。 是什么类似微信的小程序,不需要下载App,可以直接打开一个小程序,并且不需要显式的去App Store里下载。APP clips可以在不打开主App的情况下,单独进行使用,交互操作和主App无异,例如登录、列表视图、支付等。 怎么用通过Safari Banner或iMessage,点击URL链接下载和打开App,此时会弹出下面的问询窗口,告知用户是否要打开APP clips,点击open即可打开。如果已经安装主App,则打开的就是主App,所以主App和APP clips都需要支持这个URL。 下面是打开主App的Safari Banner,APP clips的应该也这个形式差不多。 配置image、subtitle等,应该是直接在Apple Developer开发者中心配置,之前一些App外的信息也都是在上面配置的。 开发TipsAPP clips由于是小程序,所以安装包大小被限制在10MB以内。并且一个主App,只能有一个APP clips。如果想开发APP clips的话,可以下载最新的Xcode12 Bate版开发,当然也需要运行在最新的iOS14系统上。APP clips的bundle id有命名要求,需要以{主App Bundle id}+Clip的格式命名。由于APP clips只支持iOS14,所以可以直接使用SwiftUI进行开发,还是比较nice的。通过Xcode12的App Clip选项即可开发自己的App Clips,开发完成后在Apple Developer配置一些展示信息即可。

July 6, 2020 · 1 min · jiezi

NSURLSession最全攻略

该文章属于<简书 — 刘小壮>原创,转载请注明:<简书 — 刘小壮> NSURLSessionNSURLSession在iOS7中推出,NSURLSession的推出旨在替换之前的NSURLConnection,NSURLSession的使用相对于之前的NSURLConnection更简单,而且不用处理Runloop相关的东西。 2015年RFC 7540标准发布了http 2.0版本,http 2.0版本中包含很多新的特性,在传输速度上也有很明显的提升。NSURLSession从iOS9.0开始,对http 2.0提供了支持。 NSURLSession由三部分构成: NSURLSession:请求会话对象,可以用系统提供的单例对象,也可以自己创建。NSURLSessionConfiguration:对session会话进行配置,一般都采用default。NSURLSessionTask:负责执行具体请求的task,由session创建。NSURLSession有三种方式创建: sharedSession系统维护的一个单例对象,可以和其他使用这个session的task共享连接和请求信息。 sessionWithConfiguration:在NSURLSession初始化时传入一个NSURLSessionConfiguration,这样可以自定义请求头、cookie等信息。 sessionWithConfiguration:delegate:delegateQueue:如果想更好的控制请求过程以及回调线程,需要上面的方法进行初始化操作,并传入delegate来设置回调对象和回调的线程。 通过NSURLSession发起一个网络请求也比较简单。 创建一个NSURLSessionConfiguration配置请求。通过Configuration创建NSURLSession对象。通过session对象发起网络请求,并获取task对象。调用[task resume]方法发起网络请求。NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];[task resume];NSURLSessionTask通过NSURLSession发起的每个请求,都会被封装为一个NSURLSessionTask任务,但一般不会直接是NSURLSessionTask类,而是基于不同任务类型,被封装为其对应的子类。 NSURLSessionDataTask:处理普通的Get、Post请求。NSURLSessionUploadTask:处理上传请求,可以传入对应的上传文件或路径。NSURLSessionDownloadTask:处理下载地址,提供断点续传功能的cancel方法。主要方法都定义在父类NSURLSessionTask中,下面是一些关键方法或属性。 currentRequest当前正在执行的任务,一般和originalRequest是一样的,除非发生重定向才会有所区别。originalRequest主要用于重定向操作,用来记录重定向前的请求。taskIdentifier当前session下,task的唯一标示,多个session之间可能存在相同的标识。prioritytask中可以设置优先级,但这个属性并不代表请求的优先级,而是一个标示。官方已经说明,NSURLSession并没有提供API可以改变请求的优先级。state当前任务的状态,可以通过KVO的方式监听状态的改变。- resume开始或继续请求,创建后的task默认是挂起的,需要手动调用resume才可以开始请求。- suspend挂起当前请求。主要是下载请求用的多一些,普通请求挂起后都会重新开始请求。下载请求挂起后,只要不超过NSURLRequest设置的timeout时间,调用resume就是继续请求。- cancel取消当前请求。任务会被标记为取消,并在未来某个时间调用URLSession:task:didCompleteWithError:方法。 NSURLSession提供有普通创建task的方式,创建后可以通过重写代理方法,获取对应的回调和参数。这种方式对于请求过程比较好控制。 - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;除此之外,NSURLSession也提供了block的方式创建task,创建方式简单如AFN,直接传入URL或NSURLRequest,即可直接在block中接收返回数据。和普通创建方式一样,block的创建方式创建后默认也是suspend的状态,需要调用resume开始任务。 completionHandler和delegate是互斥的,completionHandler的优先级大于delegate。相对于普通创建方法,block方式更偏向于面向结果的创建,可以直接在completionHandler中获取返回结果,但不能控制请求过程。 - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;可以通过下面的两个方法,获取当前session对应的所有task,方法区别在于回调的参数不同。以getTasksWithCompletionHandler为例,在AFN中的应用是用来获取当前session的task,并将AFURLSessionManagerTaskDelegate的回调都置为nil,以防止崩溃。 ...

July 6, 2020 · 6 min · jiezi

探秘AFNetworking

该文章属于<简书 — 刘小壮>原创,转载请注明:<简书 — 刘小壮> AFNetworking源码分析AFNetworking是iOS最常用的网络框架,虽然系统也有NSURLSession,但是我们一般不会直接用它。AFNetworking经过了三个大版本,现在用的大多数都是3.x的版本。 AFNetworking经历了下面三个阶段的发展: 1.0版本 : 基于NSURLConnection的封装。2.0版本 : 两套实现,分别基于NSURLConnection和NSURLSession,是转向NSURLSession的过渡版。3.0版本 : 基于NSURLSession的封装。文件构成 AFNetworking3.X的构成很简单,主要就四部分,除此之外还有一些基于UIKit的Category,但这些并不是标配。 Manager : 负责处理网络请求的两个Manager,主要实现都在AFURLSessionManager中。Reachability : 网络状态监控。Security : 处理网络安全和HTTPS相关的。Serialization : 请求和返回数据的格式化器。AFURLSessionManager在AFN3.0中,网络请求的manager主要有AFHTTPSessionManager和AFURLSessionManager构成,二者为父子关系。这两个类职责划分很清晰,父类负责处理一些基础的网络请求代码,并且接受NSURLRequest对象,而子类则负责处理和http协议有关的逻辑。 AFN的这套设计很便于扩展,如果以后想增加FTP协议的处理,则基于AFURLSessionManager创建子类即可。子类中只需要进行很少的代码处理,创建一个NSURLRequest对象后调用父类代码,由父类去完成具体的请求操作。 创建sessionManagerAFHTTPSessionManager类的初始化方法中并没有太多实现代码,其内部调用的都是父类AFURLSessionManager的initWithSessionConfiguration方法,下面是此方法内部的一些关键代码。 在初始化方法中包含一个参数sessionConfiguration,如果没有传入的话默认是使用系统的defaultConfiguration,我们创建是一般都不会自定义configuration,所以大多数都是系统的。 if (!configuration) { configuration = [NSURLSessionConfiguration defaultSessionConfiguration];}随后是NSURLSession的初始化代码,关于NSOperationQueue后面详细进行讲解。NSURLSession的初始化方式有两种,一种是使用系统的共享session,另一种是自己创建session。AFN选择的是创建自己的session,并且每个请求都会创建一个独立的session。 可以通过NSURLSession进行连接复用,这样可以避免很多握手和挥手的过程,提高网络请求速度,苹果允许iOS设备上一个域名可以有四个连接同时存在。但是由于AFN的实现是每个请求都创建一个session,所以就不能进行连接复用。 所以可以通过在外面对AFN进行二次封装,将AFHTTPSessionManager复用为单例对象,通过复用sessionManager的方式,来进行连接的复用。但是这种方案对于不同的requestSerializer、responseSerializer等情况,还是要做特殊兼容,所以最好建立一个sessionManager池,对于同类型的sessionManager直接拿出来复用,否则就创建新的。 // 共享session连接池[NSURLSession sharedSession];// 创建新session,则不能使用共享session连接池[NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];由于当前AFURLSessionManager对象的所有sessionTask请求任务,都是共享同一个回调代理的,所以AFN为了区分每个sessionTask,通过下面的可变字典,将所有taskDelegate和task.taskIdentifier的进行了一一对应,以便于很容易的对每个请求task进行操作。 self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];在初始化方法中,可以发现AFN在创建session后,调用了getTasksWithCompletionHandler方法来获取当前所有的task。但是现在刚创建session,理论上来说是不应该有task的。但从AFN的issues中找到了答案issues 3499。 这是因为,在completionHandler回调中,为了防止进入前台时,通过session id恢复的task导致一些崩溃问题,所以这里将之前的task进行遍历,并将回调都置nil。 [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { for (NSURLSessionDataTask *task in dataTasks) { [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil]; } for (NSURLSessionUploadTask *uploadTask in uploadTasks) { [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil]; } for (NSURLSessionDownloadTask *downloadTask in downloadTasks) { [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil]; }}];创建task在AFURLSessionManager中进行task的创建,task的类型总共分为三种,dataTask、uploadTask、downloadTask,AFN并没有对streamTask进行处理。 ...

July 6, 2020 · 9 min · jiezi

ScrollViewCollectionView和TableView添加UIRefreshControl实现下拉刷新

Apple在iOS 6中添加了UIRefreshControl,但只能在UITableViewController中使用,不能在UIScrollView和UICollectionView中使用。 iOS 10 新特性从iOS 10开始,UIScrollView增加了一个refreshControl属性,用于把配置好的UIRefreshControl赋值给该属性,这样UIScrollView就有了下拉刷新功能。和之前在UITableViewController中使用一样,不需要设置UIRefreshControl的frame,只需要配置UIRefreshControl。 因为UITableView和UICollectionView继承自UIScrollView,所以UITableView和UICollectionView也继承了refreshControl属性,也就是可以很方便的把刷新控件添加到滚动视图、集合视图和表视图(不再需要表视图控制器)。 截止目前,Xcode 8.2.1的Interface Builder还没有支持refreshControl属性,如果你需要在UIScrollView、UITableView和UICollectionView中使用UIRefreshControl只能通过代码添加。通过Interface Builder可以为UITableViewController 添加刷新控件。滚动视图示例这个demo使用Single View Application模板,打开storyboard,在系统创建的ViewController上添加一个UIScrollView,在UIScrollView上添加两个UILabel,并在UILabel上添加内容。想要实现的功能是,下拉刷新页面时隐藏第二个UILabel,再次刷新时显示该UILabel。 这里只对demo简单描述,如果需要查看详细代码,可以在我的GitHub中查看。另外,文章底部也会提供源码地址。创建刷新控件在UIScrollView、UITableView和UICollectionView中创建刷新控件步骤是一样的。在这个示例中,在ViewController的viewDidLoad方法中创建并配置UIRefreshControl。scrollView是连接到Interface Builder中的UIScrollView的IBOutlet属性。 - (void)viewDidLoad{ [super viewDidLoad]; // 1 先判断系统版本 if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10,0,0}]) { // 2 初始化 UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; // 3.1 配置刷新控件 refreshControl.tintColor = [UIColor brownColor]; NSDictionary *attributes = @{NSForegroundColorAttributeName : [UIColor redColor]}; refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull To Refresh" attributes:attributes]; // 3.2 添加响应事件 [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; // 4 把创建的refreshControl赋值给scrollView的refreshControl属性 self.scrollView.refreshControl = refreshControl; }}注意以下几点: ...

July 1, 2020 · 1 min · jiezi

腾讯-‘iOS开发-部门3次挂了这次成功拿下岗位面试题附答案

前言最近在网上找了不少面试相关的资料学习准备面试!之前面了一个部门3次挂了.....尴尬 有记录面试题, 希望对你们有帮助~! 少走一些弯路! 请看答案在最下面!! 腾讯一面介绍你做过的项目难点?OC修饰符,追问weak,unsafe_unretained什么意思? 为什么NSString要加copy? 4.4. KVO的原理是什么? RN基础架构是什么? 做过哪些性能优化? 有没有遇到什么卡顿的情况?怎么处理的? HTTPS和HTTP区别,追问具体怎么加密,如何信任证书 HTTP2.0和HTTP1.1区别 TCP接受窗口和发送窗口,TCP 3次握手 数组和链表的区别,使用场景分别是什么 算法题:给定50个已排序数组,每个里面200个数,找出其中最小的200个数 描述思路,追问时间复杂度,追问还有没有其他方法。描述思路,继续追问复杂度,问有没其他方法。线下写完代码发送到邮箱。 算法复试4道一共有算法题,要求写出可编译代码。 反转一个链表 给定一个数组,其中有一个数只出现一次,其他数都出现两次,找到只出现一次的那个数。 实现堆排序给定一个数组array,其中array[i] != array[i+1],找到任何一个i,满足array[i] > array[i-1] 且 array[i] > array[i+1]。假设array[-1] == array[n] == 负无穷。要求O(logN)时间复杂度。6.2 二面算法题翻转k个链表 (写代码) 如何拷贝一个包含随机指针的链表 (描述思路) 问答 (因为我简历写做过RN,面试官刚好也做过) 描述一下RN渲染过程 你使用RN的时候有遇到什么问题?什么地方导致RN性能瓶颈? OC对象内存结构,isa指针有什么用,根源类是什么? _weak自动重置nil具体如何实现? MSS和MTU是什么,具体怎么确定 交叉面试你觉得熟悉iOS哪些框架? 为什么UI更新必须在主线程? 追问:具体哪些冲突? 追问:还有吗? 追问:如果强行开一个子线程,把事件处理和ui更新都放进去,是不是可以解决你说的冲突? 了解过Xcode编译过程?了解过bitcode吗? 你了解哪些设计模式?具体描述一下? 研究生什么方向?答:VR。追问:3D渲染的具体过程。 面试资料:看完文章如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。

June 29, 2020 · 1 min · jiezi

教你打造一套移动端-APM-监控系统

APM 是 Application Performance Monitoring 的缩写,监视和管理软件应用程序的性能和可用性。应用性能管理对一个应用的持续稳定运行至关重要。所以这篇文章就从一个 iOS App 的性能管理的纬度谈谈如何精确监控以及数据如何上报等技术点App 的性能问题是影响用户体验的重要因素之一。性能问题主要包含:Crash、网络请求错误或者超时、UI 响应速度慢、主线程卡顿、CPU 和内存使用率高、耗电量大等等。大多数的问题原因在于开发者错误地使用了线程锁、系统函数、编程规范问题、数据结构等等。解决问题的关键在于尽早的发现和定位问题。 本篇文章着重总结了 APM 的原因以及如何收集数据。APM 数据收集后结合数据上报机制,按照一定策略上传数据到服务端。服务端消费这些信息并产出报告。请结合姊妹篇, 总结了如何打造一款灵活可配置、功能强大的数据上报组件。 一、卡顿监控卡顿问题,就是在主线程上无法响应用户交互的问题。影响着用户的直接体验,所以针对 App 的卡顿监控是 APM 里面重要的一环。 FPS(frame per second)每秒钟的帧刷新次数,iPhone 手机以 60 为最佳,iPad 某些型号是 120,也是作为卡顿监控的一项参考参数,为什么说是参考参数?因为它不准确。先说说怎么获取到 FPS。CADisplayLink 是一个系统定时器,会以帧刷新频率一样的速率来刷新视图。 [CADisplayLink displayLinkWithTarget:self selector:@selector(###:)]。至于为什么不准我们来看看下面的示例代码 _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(p_displayLinkTick:)];[_displayLink setPaused:YES];[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];代码所示,CADisplayLink 对象是被添加到指定的 RunLoop 的某个 Mode 下。所以还是 CPU 层面的操作,卡顿的体验是整个图像渲染的结果:CPU + GPU。请继续往下看 1. 屏幕绘制原理 讲讲老式的 CRT 显示器的原理。 CRT 电子枪按照上面方式,从上到下一行行扫描,扫面完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;当一帧画面绘制完成后,电子枪恢复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(Vertical synchronization),简称 VSync。显示器通常以固定的频率进行刷新,这个固定的刷新频率就是 VSync 信号产生的频率。虽然现在的显示器基本都是液晶显示屏,但是原理保持不变。 ...

June 28, 2020 · 67 min · jiezi

iOS-动画-窗景篇三完结

这篇文章是系列文章的第三篇。 看过上一篇文章的朋友,已经知道标题中的“景”指代 view,“窗”指代 view.mask,窗景篇就是在梳理 mask 及 mask 动画。如果你还不熟悉 iOS 的 mask,建议先看一下第一篇。 前两篇我们介绍了 mask、mask 动画的一些用法。 这一篇作为收尾,我们来实现一个效果练练手,也借这个效果,让大家回忆起一个简单的道理:复杂的效果,可以等价于简单效果的组合。 一、效果这个效果如下面的动图所示: 我们截取比较有代表性的一帧,如下图所示: 从图中可以看到,波浪由两种颜色组成,各部分颜色不同。 这个效果看上去有点复杂,如果不熟悉 mask,可能一时半会儿没有思路。但看过前两篇的朋友,可能已经暗暗在想,是窗在动?还是景在动?会不会有多套窗景? 那么接下来,我们先通过一个简单的效果来看一下原理。 注:波浪动画的实现和本文关系不大,本文不会讲述。网上有成熟的波浪动画的教程,本文 demo 中 WaveView 类也有简要的注释。一、一个简单的效果这个效果如下图所示: 从图中可以看到,一张黑白图片上有一部分是彩色的。我们当然可以通过图像处理来实现这个效果,但在本文中,我们还是使用 mask 的方式来实现。 我们回忆一下前文中的一张图: 通过对frontView 添加一个圆 mask,就形成了图中的效果。 也许有的朋友已经想到,把上图中 backView 的图换成和 frontView 一样的黑白图片,不就是本例的效果吗,如下图所示: 也就是说,这个效果看上去是黑白图片上有一部分变成了彩色,但其实只是两张内容一样的图片重叠,黑白图片在后,彩色图片在前,而前方的彩色图片,被施加了圆形的 mask。 这个效果很简单,但能让我们意识到一件事:看上去是一张图,其实可能是多张图组合而成。 既然如此,那本文的波浪动画中,各部分颜色不同的波浪,真的只是一个波浪吗? 没错,本例中的波浪,也是多个波浪组合而成的,接下来,我们就详细的看一看。 二、多景合一和黑白、彩色图片重叠效果一样,多色波浪也是由一组重叠的波浪 view 组合而成。 每层 view 的波浪只有一种颜色,各层 view 的波浪动画都一致,对于每一帧,所有波浪都是完全重合的。 每个波浪 view 都有自己的 mask,在 mask 们 的控制下,每层波浪 view 只显示了波浪的一部分,我们看到的多色波浪,就是各层波浪 view 可见部分的组合。 ...

June 28, 2020 · 2 min · jiezi

iOS笔记-1SEL的原理与使用

概念SEL:方法名(编号)IMP:一个函数指针,保存了方法的地址@selector(方法名)获取方法的编号,结果是SEL类型。他的行为基本可以等同于C语言中的函数指针区别 C语言中,可以直接把函数名赋值给一个函数指针,而且函数指针直接保存了函数地址Objc中的类不能直接应用函数指针,只能使用@selector来获取,获取的是方法的编号方法以@selector作为索引,@selector的数据类型是SEL,对应每个方法的编号,当我们寻找方法的时候使用的是这个方法编号。类中存在一个methodLists专门用来存放方法实现IMP和SEL的映射。方法编号SEL通过Dispatch table表寻找到对应的IMP,IMP就是一个函数指针,然后执行这个方法。 struct objc_class {    struct objc_class super_class;  /*父类*/    const char *name;                 /*类名字*/    long version;                   /*版本信息*/    long info;                        /*类信息*/    long instance_size;               /*实例大小*/    struct objc_ivar_list *ivars;     /*实例参数链表*/    struct objc_method_list **methodLists;  /*方法链表*/    struct objc_cache *cache;               /*方法缓存*/    struct objc_protocol_list *protocols;   /*协议链表*/};typedef struct objc_method *Method;typedef struct objc_ method { SEL method_name; //方法名 char *method_types; //参数类型 IMP method_imp; //方法实现};相关class   返回对象的类;isKindOfClass 和 isMemberOfClass检查对象是否在指定的类继承体系中;respondsToSelector 检查对象能否相应指定的消息;conformsToProtocol 检查对象是否实现了指定协议类的方法;methodForSelector  返回指定方法实现的地址。performSelector:withObject 执行SEL 所指代的方法。具体实现在寻找IMP的地址时,runtime提供了两种方法: IMP class_getMethodImplementation(Class cls, SEL name);IMP method_getImplementation(Method m)而根据官方描述,第一种方法可能会更快一些 ...

June 26, 2020 · 1 min · jiezi

编码1蜜蜂采蜜

一朵花有Open和Close两种状态,3只蜜蜂在花Open的时候去采蜜,在花Close的时候回巢,用面向对象技术和Design Pattern方法模拟上面过程,输出如下: Flower openBee 1's eating time!Bee 2's eating time!Bee 3's eating time!Floer closeBee 1's bed time!Bee 2's bed time!Bee 3's bed time!编码实现上述情景,要求使用一种Design Pattern方法,使花和蜜蜂之间松耦合。 protocol ObserverProtocol { var id: Int {get set} func onValueChanged(_ value: Any?)}protocol ObservableProtocol: class { var observers: [ObserverProtocol] {get set} func addObserver(_ observer: ObserverProtocol) func removeObserver(_ observer: ObserverProtocol) func notifyObservers(_ observers: [ObserverProtocol])}class Observable<T>: ObservableProtocol { var value: T { didSet { self.notifyObservers(self.observers) } } internal var observers: [ObserverProtocol] = [] init(value: T) { self.value = value } func addObserver(_ observer: ObserverProtocol) { guard self.observers.contains(where: { $0.id == observer.id}) == false else { return } self.observers.append(observer) } func removeObserver(_ observer: ObserverProtocol) { guard let index = self.observers.firstIndex(where: { $0.id == observer.id}) else { return } self.observers.remove(at: index) } func notifyObservers(_ observers: [ObserverProtocol]) { observers.forEach({$0.onValueChanged(value)}) } deinit { observers.removeAll() }}enum FlowerStatus: String { case open = "Flower open" case close = "Flower close"}class Flower: Observable<FlowerStatus> { var status: FlowerStatus { get { return self.value } set { print(newValue.rawValue) self.value = newValue } }}struct Bee: ObserverProtocol { var id: Int var name: String func onValueChanged(_ value: Any?) { if let status = value as? FlowerStatus { if status == .open { print("\(name)'s eating time!") } else { print("\(name)'s beding time!") } } }}func beeTime() { let flower = Flower(value: .close) let bee1 = Bee.init(id: 1, name: "Bee 1") let bee2 = Bee.init(id: 2, name: "Bee 2") let bee3 = Bee.init(id: 3, name: "Bee 3") flower.addObserver(bee1) flower.addObserver(bee2) flower.addObserver(bee3) flower.status = .open flower.status = .close}beeTime()Observable另一种实现,注意,这种方法实现,打印是无序的 ...

June 24, 2020 · 2 min · jiezi

OC-语法快速入门

来源: https://www.runoob.com/w3cnot... Interface定义部分,清楚定义了类的名称、数据成员和方法。 以关键字@interface作为开始,@end作为结束。 @interface MyObject : NSObject { int memberVar1; // 实体变量 id memberVar2;}+(return_type) class_method; // 类方法-(return_type) instance_method1; // 实例方法-(return_type) instance_method2: (int) p1;-(return_type) instance_method3: (int) p1 andPar: (int) p2;@end方法前面的 +/- 号代表函数的类型:加号(+)代表类方法(class method),不需要实例就可以调用,与C++ 的静态函数(static member function)相似。减号(-)即是一般的实例方法(instance method)。 这里提供了一份意义相近的C++语法对照,如下: class MyObject : public NSObject {protected: int memberVar1; // 实体变量 void * memberVar2; public: static return_type class_method(); // 類方法 return_type instance_method1(); // 实例方法 return_type instance_method2( int p1 ); return_type instance_method3( int p1, int p2 );}Objective-C定义一个新的方法时,名称内的冒号(:)代表参数传递,不同于C语言以数学函数的括号来传递参数。Objective-C方法使得参数可以夹杂于名称中间,不必全部附缀于方法名称的尾端,可以提高程序可读性。设定颜色RGB值的方法为例: ...

June 17, 2020 · 2 min · jiezi

OCPromise用OC实现JS的Promise

OCPromise是参考的Javescript中的Promise写的一套用Objective-C实现的异步任务队列管理的链式操作工具。 写这套库的想法是源自一次面试的失败经历:之前在工作中我使用过React native进行开发,因此也写过Javascript代码并且使用过Promise语法,但是在一次面试中,面试官让我手写Promise的实现,当时我直接懵了,才发现在开发过程中很多东西实现过一次之后,后面再用到时直接复制粘贴再改一改,结果就是这些东西根本没有变成自己的知识,甚至对它的理解也很片面。 回想起来,Promise的调用方式还是很有意思的,链式的语法使用起来也很美观,因此我尝试用OC实现了Promise的功能,OCPromise提供的功能可以参考这篇关于JS-Promise的文章:理解 Javascript 中的 Promise,我在写OCPromise时也是完全参照的Promise,只不过由于语法的差异性,调用方法会略有不同。 下面我先介绍一下OCPromise的使用方法: OCPromise的创建 OCPromise *p = Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"start new Promise..."); resolve(@123); }); OCPromise *multiply = function(^OCPromise * _Nullable(id _Nonnull value) { return Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"calculating %ld x %ld ...", [value longValue], [value longValue]); resolve([NSNumber numberWithLong:[value longValue] * [value longValue]]); }); }); OCPromise *add = function(^OCPromise * _Nullable(id _Nonnull value) { return Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"calculating %ld + %ld ...", [value longValue], [value longValue]); resolve([NSNumber numberWithLong:[value longValue] + [value longValue]]); }); });使用Promise()函数创建的Promise对象可以处理独立的任务,而使用function()函数创建Promise对象时,实际Promise对象的创建延迟到^OCPromise *(id value) {}执行时期,并且Promise的任务执行期间value可以参与内部的Promise()任务的执行的(也可以不参与)。 ...

June 16, 2020 · 4 min · jiezi

OCPromise进阶用法

OCPromise-用OC实现JS的Promise上篇文章介绍了OCPromise的基本用法,这篇里我将介绍几个扩展方法。 deliverOnMainThread上篇结尾处提到过,OCPromise的任务都是在子线程上执行的,那么我们在接收任务结果时,如果需要进行UI的操作时,还需要自己手动切到主线程上,因此我提供了一个将任务结果传递到主线程的回调方法: OCPromise *p = Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"start new Promise..."); resolve(@123); }); OCPromise *multiply = function(^OCPromise * _Nullable(id _Nonnull value) { return Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"calculating %ld x %ld ...", [value longValue], [value longValue]); resolve([NSNumber numberWithLong:[value longValue] * [value longValue]]); }); }); OCPromise *add = function(^OCPromise * _Nullable(id _Nonnull value) { return Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { NSLog(@"calculating %ld + %ld ...", [value longValue], [value longValue]); resolve([NSNumber numberWithLong:[value longValue] + [value longValue]]); }); }); p.then(multiply).deliverOnMainThread(^(id _Nonnull value) { NSLog(@"1 got value %@ on %@", value, [NSThread currentThread]); }).then(function(^OCPromise * _Nullable(id _Nonnull value) { NSLog(@"2 got value %@ on %@", value, [NSThread currentThread]); return Promise(^(resolve _Nonnull resolve, reject _Nonnull reject) { resolve(@([value longValue] * 10)); }); })).then(add).deliverOnMainThread(^(id _Nonnull value) { NSLog(@"3 got value %@ on %@", value, [NSThread currentThread]); }).then(function(^OCPromise * _Nullable(id _Nonnull value) { NSLog(@"4 got value %@ on %@", value, [NSThread currentThread]); return nil; }));2020-06-11 16:10:37.224503+0800 OCPromise_Example[56255:2885996] start new Promise...2020-06-11 16:10:37.224690+0800 OCPromise_Example[56255:2885996] calculating 123 x 123 ...2020-06-11 16:10:37.224909+0800 OCPromise_Example[56255:2885925] 1 got value 15129 on <NSThread: 0x6000022c85c0>{number = 1, name = main}2020-06-11 16:10:37.224920+0800 OCPromise_Example[56255:2885996] 2 got value 15129 on <NSThread: 0x60000228a300>{number = 6, name = (null)}2020-06-11 16:10:37.225055+0800 OCPromise_Example[56255:2885996] calculating 151290 + 151290 ...2020-06-11 16:10:37.225182+0800 OCPromise_Example[56255:2885996] 4 got value 302580 on <NSThread: 0x60000228a300>{number = 6, name = (null)}2020-06-11 16:10:37.225188+0800 OCPromise_Example[56255:2885925] 3 got value 302580 on <NSThread: 0x6000022c85c0>{number = 1, name = main}通过打印结果我们可以看到1、3都是在主线程执行的,并且主线程的接收并不影响子线程任务结果在任务链中的传递。deliverOnMainThread的实际调用逻辑就是在子线程接收到上一个任务的结果,然后为主线程添加一个异步任务来执行外部回调将结果传出去,并在当前线程继续将任务结果传递给下一个任务。 ...

June 16, 2020 · 3 min · jiezi

iOS无侵入埋点方案如何实现

在开发过程中,埋点可以解决两大类问题:一是了解用户使用 App 的行为,二是降低分析线上问题的难度。目前,iOS 开发中常见的埋点方式,主要包括: 代码埋点可视化埋点无埋点代码埋点 代码埋点主要就是通过手写代码的方式来埋点,能很精确的在需要埋点的代码处加上埋点的代码,可以很方便地记录当前环境的变量值,方便调试,并跟踪埋点内容,但存在开发工作量大,并且埋点代码到处都是,后期难以维护等问题。 缺点: 显而易见,你会在后期维护的时候写的怀疑人生复用性差,几乎不能移植给其他项目工作量大,而且会越写越多统计代码上线之后,如果出现问题,只能后续版本迭代如果统计项目名字改变了,原来老的APP版本依旧会统计老的页面名字优点: 如果非要写一个其他统计无法做到的优点的话,那就是可自定义程度高吧,统计代码想写到那里写到那里(其实这些也可以在后面的方案实现,只是实现上稍微麻烦一点罢了)最容易想到的方案(前期费时少,使用起来费手不费思路)可视化埋点 就是将埋点增加和修改的工作可视化了,提升了增加和维护埋点的体验。 该方案的具体步骤就是: 从后台获取需要统计的地方hook住需要统计的类的load方法来Method Swizzing要统计的方法上传统计到的事件给后台分析用UIViewController、UIControl为例子,讲解一下该方案的思路。 UIViewController PV统计,页面的统计较为简单,利用Method Swizzing hook 系统的viewDidLoad, 直接通过页面名称即可锁定页面的展示代码如下: UIControl 点击统计,主要通过hook sendAction:to:forEvent: 来实现, 其唯一标识符我们用 targetname/selector/tag来标记,具体代码如下: 缺点: 需要后台配合可拓展性不是很高,因为需要修改后台下发的统计内容来做每次的版本统计扩展优点: 相对于第一种方案,代码量少了很多。动态化从后台获取统计内容,方便线上修改无埋点 无埋点,并不是不需要埋点,而更确切地说是“全埋点”,而且埋点代码不会出现在业务代码中,容易管理和维护。它的缺点在于,埋点成本高,后期的解析也比较复杂,再加上 view_path 的不确定性。所以,这种方案并不能解决所有的埋点需求,但对于大量通用的埋点需求来说,能够节省大量的开发和维护成本。 在这其中,可视化埋点和无埋点,都属于是无侵入的埋点方案,因为它们都不需要在工程代码中写入埋点代码。所以,采用这样的无侵入埋点方案,既可以做到埋点被统一维护,又可以实现和工程代码的解耦。 接下来,我们就通过今天这篇文章,一起来分析一下无侵入埋点方案的实现问题吧。 运行时方法替换方式进行埋点 我们都知道,在 iOS 开发中最常见的三种埋点,就是对页面进入次数、页面停留时间、点击事件的埋点。对于这三种常见情况,我们都可以通过运行时方法替换技术来插入埋点代码,以实现无侵入的埋点方法。具体的实现方法是:先写一个运行时方法替换的类 ViewHook,加上替换的方法 hookClass:fromSelector:toSelector,代码如下: 这个方法利用运行时method_exchangeImplementations 接口将方法的实现进行了交换,原方法调用时就会被hook 住,从而去执行指定的方法。 页面进入次数、页面停留时间都需要对 UIViewController 生命周期进行埋点,你可以创建一个 UIViewController 的 Category,代码如下: 可以看到,Category 在+load() 方法里使用了 ViewHook 进行方法替换,在替换的方法里执行需要埋点的方法 [self insertToViewWillAppear]。 这样的话,每个UIViewController生命周期到了ViewWillAppear 时都会去执行insertToViewWillAppear 方法。 那么,我们要怎么区别不同的 UIViewController 呢?我一般采取的做法都是,使用NSStringFromClass([self class]) 方法来取类名。这样,我就能够通过类名来区别不同的 UIViewController 了。 ...

June 13, 2020 · 1 min · jiezi

中高级iOS大厂面试宝典

引言过年之后相信有一部分的人,早已磨刀霍霍向大厂。势必要大展拳脚,必将在大厂内创出一片天地。但是,想必大家都知道:最近几年的最严重的互联网寒冬来临,各位兄弟都会说“江湖再见”。耳边总是充刺着流言蜚语,这个地方裁员了,这个地方缩减HC。弄得人心慌慌。年后将是一片血雨腥风,程序界的江湖将在这一天精彩斑斓。 但我们要知道,寒冬之中,什么是最珍贵,就让鄙人告诉你:人才。只要有过硬的技术和装备,在逆风直下的情况下,咱们也能迎难而上,打他个戳手不及。不是“李云龙”大哥说:“过狭路相逢勇者胜.” 最近几天看了朋友,到处厮杀,经过一番斗争,最终夺下头筹获得多家大厂的offer。 承蒙兄弟抬爱,感情深厚。拿出《iOS中高级面试宝典》赠与小弟参悟。经过小弟我的反复参悟和整理,现在共享出来,希望与大家一起学习参悟。小弟我先说一下,面试虽然有技巧,但咋们绝不是吹嘘与伪造之辈,因先当花点时间静心闭关修炼,带到出关之日,必进大厂,薪资翻倍,岂不快哉!!! 参悟规则作为一名优秀的程序员,肯定是不会浪费时间在一个 : 一:没有晋升,没有职业发展的公司 二:也不会停留在某一个技术层面不前进的公司 三:我愿付出真心,你却不愿有待我的公司 本博客的知识点较多,花点时间一个个理解并记忆后,自然也就融会贯通,无所畏惧。面试iOS也就分分钟 本宝典为了便于记忆,快速达到应试状态,类似于复习知识大纲。知识点会尽量的精简与提炼知识脉络,并不去展开深入细节,面面俱到。有兴趣或者有疑问的兄弟可以自行谷歌下对应知识点的详细内容。 作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:761407670 进群密码‘思否’,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!1、swift和oc的区别(1) Swit没有地址指针的概念 (2)泛型 (3)类型严谨对比oc的动态绑定 2、编译连接id和instancetype的区别instancetype只能故返回值编译时判断真实类型,不符合发警告特殊情况:关联类型返回方法如类方法lloc或new开头实例方法中,以autorelease,init,retain,或self开头3、synthesize & denamic1:通过@sythesize 指令告诉编译器在编译期间产生getter/setter方法。 2:通过@dynamic指令,自己实现方法。 有些存取是在运行时动态创建的,如在CoreData的NSManagedObject类使 4、在项目开发中常用的开发工具有哪些?instrumentbeyondComparegit5、UlTableView & UlCollectionUlCollectionView是iOS6新引进的API,用于展示集合视图,布局更加灵活,其用法类似于UITableView。而UICollectionView、UlCollectionViewCell与UITableView、UITableViewCell在用法上有相似的也有不同的, 下面是一些基本的使用方法:对UITableView,仅需要UITableViewDataSource,UITableViewDelegate这两个协议使用UlCollectionView需要实现:UICollectionViewDataSource,UlCollectionViewDelegate, UlCollectionViewDelegateFlowLayout这三个协议.这是因为UlCollectionViewDelegateFlowL ayou实际上是UCollectionViewDelegate的一个子协议,它继承了 UlCollectionViewDelegate,它的作用是提供一些定义UlCollectionView布局模式的函数6、NSProxy & NSObjectNSObjetct:NSObject协议组对所有的Object -C下的objects都生效。如果objects遵从该协议,就会波看作是first -class objects (- 级类)。另外, 遵从该协议的objects的retain, release, autorelease等 方法也服从objects的管理和在 Foundation中定义的释放方法。- -些容器中的对象也可以管理这些objects,比如说NSArray和NSDictionary定义的对象。Cocoa的根类也遵循该协议,所以所有继承NSObjects的 objects都有遵循该协议的特性。NSProXY:NSProxy是一个虚基类,它为一些表现的像是其它对象替身或者并不存在的对象定义一套API。 -般 的,发送给代理的消息被转发给一个真实的对象或者代理本身load(或者将本身转换成)一个真实的对象。NSProxy的基类可以被用来透明的转发消息或者耗费巨大的对象的lazy初始化。7、Object & SwiftObejective-C复杂的语法,更加简单易用、有未来,让许多开发者心动不已.苹果宣称Swift的特点是:快速、现代、安全、互动,而且明显优于Objective-C语言 可以使用现有的Cocoa和Cocoa Touch框架 Swift取消了Objective C的指针及其他不安全访问的使用舍弃Objective C早期应用Smalltalk的语法,全面改为句点表示法提供了类似Java的名字空间(namespace)、 泛型(generic)、运算对象重载(operator overloading) Swift 被简单的形容为“没有C的Objective-C" (Objective- C without theC)为苹果开发工具带来了XcodePlaygrounds功能,该功能提供强大的互动效果,能让Swift源代码在撰写过程中实时显示出其运行结果; 基于C和Objective-C,而却没有C的一些兼容约束; 采用了安全的编程模式;界面基于Cocoa和Cocoa Touch框架;保留Smaltalk的动态特性8、传值通知&推送通知(本地&远程)传值通知:类似通知,代理,Block实现值得传递 推送通知:推送到用户手机对应的App上(主要是不再前台的情况)本地通知。 local notfication,用于基于时间行为的通知,比如有关日历或者todo列表的小应用。另外,应用如果在后台执 行,iOS允许它在受限的时间内运行,它也会发现本地通知有用。比如,一个应用,在后台运行,向应用的服 务器端获取消息,当消息到达时,比如下载更新版本的提示消息,通过本地通知机制通知用户。 ...

June 13, 2020 · 1 min · jiezi

22个iOS开发常用的开源项目

分享近期 GitHub 上比较流行的 22 个和 iOS 开发相关的开源项目。 包括开发辅助工具,异步编程库,JSON 解析,移动端数据库,图像视频处理,网络请求,UI 框架、组件,算法、数据结构等内容。 Accio 使用 Swift 编写的 iOS/tvOS/watchOS/macOS 依赖管理工具。 在当前 iOS 生态环境中,CocoaPods 和 Carthage 是最成熟的依赖管理器。 如果你不喜欢使用 Ruby 编写的 CocoaPods,或者更偏爱 Carthage 的非侵入方式,可以尝试下 Accio. Accio 改进了 Carthage 的一些问题,同时它的核心尽可能使用 SwiftPM,这样未来 Xcode 对 SwiftPM 支持更成熟时,可以很方便地迁移到 SwiftPM。 顺便提一下,Accio 读作 AH-kee-oh. SwiftLint 检查 Swift 代码风格、惯例。基于 Clang 和 SourceKit 提供的 AST 表示,因此可以提供更精准的分析结果。 idb 顾名思义,iOS 版本的 adb。这款 Facebook 开发的命令行工具可助你自动化在模拟器和真机上的调试流程。 InAppViewDebugger 供内嵌于应用的视图调试器。类似 Xcode 视图调试器,但可以在 iPad 和 iPhone 上调试视图。 MTHawkeye 美图秀秀开源的 iOS 调试优化辅助工具集。 内置插件有 LivingObjectSniffer (跟踪对象)、Allocations(跟踪实时分配内存)、UITimeProfiler(主线程耗时任务调优)、ANRTrace(捕获卡顿事件)、FPSTrace(跟踪界面 FPS 及 OpenGL 刷新绘制 FPS)、CPUTrace(跟踪 CPU 持续高使用率)、NetworkMonitor(监听记录应用内 HTTP(S) 网络请求各阶段耗时)、NetworkInspect(基于 Network Monitor 推荐可优化项,支持自定义规则)、OpengGLTrace(跟踪 OpenGL 资源内存占用)、DirectoryWatcher(跟踪沙盒文件夹大小)、FLEX(沙盒文件 AirDrop)。 ...

June 13, 2020 · 1 min · jiezi

MD5-AES-RSA对数据加密传输

网络安全面临的问题有 窃听、篡改、仿冒。这三种攻击方式,分别会破坏消息的私密性、完整性和通信双方的互信。 一 单向加密 哈希HASH散列 严格意义上不算一种加密算法MD5(Message Digest algorithm 5):消息摘要算法SHA(Secure Hash Algorithm):安全散列算法HMAC(Hash Message Authentication Code):散列消息鉴别码 给定一个密钥,对明文进行密钥拼接,并且做"两次散列",得到32位结果。CRC(Cyclical Redundancy Check):循环冗余码校验 MD5加密的特点:MD5Hash算法的特点:1:输入任意长度的信息,经过摘要处理,输出为32位字符(128位)的信息.(数字指纹)2:不同输入产生不同的结果,(唯一性)3:根据128位的输出结果不可能反推出输入的信息(不可逆) 不可逆运算对不同的数据加密的结果是定长的32位字符(不管文件多大都一样)对相同的数据加密,得到的结果是一样的(也就是复制)。抗修改性 : 信息“指纹”,对原数据进行任何改动,哪怕只修改一个字节,所得到的 MD5 值都有很大区别.弱抗碰撞 : 已知原数据和其 MD5 值,想找到一个具有相同 MD5 值的数据(即伪造数据)是非常困难的.强抗碰撞: 想找到两个不同数据,使他们具有相同的 MD5 值,是非常困难的 MD5 应用:一致性验证:MD5将整个文件当做一个大文本信息,通过不可逆的字符串变换算法,产生一个唯一的MD5信息摘要,就像每个人都有自己独一无二的指纹,MD5对任何文件产生一个独一无二的数字指纹。 SHA安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。当让除了SHA1还有SHA256以及SHA512等。 SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。 MD5和SHA的比较因为二者均由 MD4 导出,SHA-1 和 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同: 对强行攻击的安全性最显著和最重要的区别是 SHA-1 摘要比 MD5 摘要长 32 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对 MD5 是 2^128 数量级的操作,而对 SHA-1 则是 2^160 数量级的操作。这样,SHA-1 对强行攻击有更大的强度。 ...

June 10, 2020 · 1 min · jiezi

iOS本地缓存方案之YYCache源码解析

iOS持久化方案有哪些?简单列举一下,iOS的本地缓存方案有挺多,各有各的适用场景: NSUserDefault : 系统提供的最简便的key-value本地存储方案,适合比较轻量的数据存储,比如一些业务flag。主要原因还是其底层是用plist文件存储的,在数据量逐步变大后,可能会发生性能问题。 存文件,归档:无论是自己转换业务数据为二进制再writeFile,还是直接利用系统的NSKeyedArchiver接口归档成文件,都属于文件存储的方案。优势是开发简单,业务可以自行控制单文件的存储内容以避免可能发生的性能问题。 sqlite、FMDB:底层利用到数据的存储方案,比较适用数据量大,有查询,排序等需求的存储场景,缺点就是开发略复杂一些。 CoreData、其他ORM方案:CoreData感觉好像应用并不是很广泛? Key-Value接口的缓存方案:这里特指提供Key-Value形式接口的缓存库,底层缓存可能使用文件或者sqlite都有。本文讨论的YYCache底层是混合使用文件+sqlite的存储方式。基于接口简便,性能优于NSUserDefault的特性,应该适用于大多数的业务场景,但是无法适用上面数据库类似的使用场景。 聊聊YYCache的优秀设计这里其实yy大神本人在博文《YYCache 设计思路》中对其设计思路有比较详尽的介绍,建议大家可以先去读一读,本文就其相对于其他缓存库的一些优势点聊一聊。 高性能的线程安全方案首先高性能是YYCache比较核心的一个设计目标,挺多代码逻辑都是围绕性能这个点来做的。 作为对比,yy提出了TMMemoryCache方案的性能缺陷。TMMemoryCache的线程安全采用的是比较常见的通过dispatch_barrier来保障并行读,串行写的方案。该方案我在上一篇《AFNetworking源码解析与面试考点思考》中有介绍。那么TMMemoryCache存在性能问题的原因会是因为其dispatch_barrier的线程安全方案吗? 答案应该在其同步接口的设计上: - (id)objectForKey:(NSString *)key{ if (!key) return nil; __block id objectForKey = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [self objectForKey:key block:^(TMMemoryCache *cache, NSString *key, id object) { objectForKey = object; dispatch_semaphore_signal(semaphore); }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); #if !OS_OBJECT_USE_OBJC dispatch_release(semaphore); #endif return objectForKey;}TMCache在同步接口里面通过信号量来阻塞当前线程,然后切换到其他线程(具体代码在其异步接口里面,是通过dispatch_async到一个并行队列来实现的)去执行读取操作。按照yy的说法主要的性能损耗应该在这个线程切换操作,同步接口没必要去切换线程执行。 yy这边的思路是通过自旋锁来保证线程安全,但仍然在当前线程去执行读操作,这样就可以节省线程切换带来的开销。(不过我在YYCache的最新代码里看到的是普通的互斥锁,并没有用自旋锁,应该是后面又做了方案上的修改?) 除了加锁串行,dispatch_sync实现同步的方案是否可行呢?除了yy提供的加锁串行方案,我们来看看前面介绍过的barrier并行读串行写方案是否也存在性能问题。如果使用该方案,同步接口可能是这样的: - (id)objectForKey:(NSString *)key{ __block id object = nil; dispatch_sync(concurrent_queue, ^{ object = cache[key]; // 读接口,不用barrier,保证读与读能够并行 }); return object;}- (void)setObject:(id)object forKey:(NSString *)key{ dispatch_barrier_sync(concurrent_queue, ^{ // 写接口,barrier保证与读互斥 cache[key] = object; });}经过demo验证,可以发现虽然是dipatch到一个concurrent_queue中执行,但是由于是sync同步派发,实际上并不会切换到新的线程执行。也就是说该方案也能做到节省线程切换的开销。 ...

June 8, 2020 · 2 min · jiezi

iOS-动画-窗景篇二

本文是系列文章的第二篇。 看过上一篇文章的同学,已经知道标题中的“景”指代 view,“窗”指代 view.mask,窗景篇就是在梳理 mask 及 mask 动画。如果你还不熟悉 iOS 的 mask,建议先看一下第一篇。 相对于景来说,窗的变化更多样一些,所以本文我们重点来看一下窗的效果。 我们从3个维度来看:窗在动吗?窗在变吗?有几个窗? 很多动画就是这3个维度的单独体现,或者组合后的效果。我们先看一下各个维度的单独效果,然后再来看一下它们的组合效果。 一、窗动前文中,我们用一个圆作为窗,先贴张图回忆一下: 我们大都做过基本的动画,因此可以想到,只要动画地改变圆 mask 的中心位置,就可以让窗动起来。 效果如下面的动图所示: 示意代码如下: /// viewDidLoad// 景frontView.frame = UIScreen.main.boundsview.addSubview(frontView)// 圆窗let mask = CircleView()mask.frame = CGRect(x: 0, y: 0, width: 200, height: 200)mask.center = CGPoint(x: 100, y: 100)self.mask = maskfrontView.mask = mask// 窗动startAnimation()/// startAnimation// 动画地改变 mask 的中心private func startAnimation() { mask.layer.removeAllAnimations() let anim = CAKeyframeAnimation(keyPath: "position") let bound = UIScreen.main.bounds anim.values = [CGPoint(x: 100, y: 250), CGPoint(x:bound.width - 100 , y: 250), CGPoint(x: bound.midX, y: 450), CGPoint(x: 100, y: 250)] anim.duration = 4 anim.repeatCount = Float.infinity mask.layer.add(anim, forKey: nil)}让窗动起来非常简单,这简单的效果也可以成为其他效果的基础。 ...

June 8, 2020 · 4 min · jiezi

事件池当然-RxSwift-做的非常好

网络请求到的数据, BehaviorSubject 作为事件仓库 store, BehaviorSubject 用户行为事件源, 保持住最新的事件。 用户行为点击,采用 PublishSubject 即时事件源,马上 fire ,作为开关,发起 BehaviorSubject 存储的事件 场景:网络请求到的数据,不是马上展示。是用户点击某个按钮后,才展示网络请求到的数据,不是马上展示,就需要用 BehaviorSubject 把这个事件 hold 住。 用户点击某个按钮后,才展示。采用 PublishSubject, 作为上面事件的开关,fire 开启事件 代码部分: struct PerViewModel { private let inputTap = PublishSubject<Bool>() private let inputNet = BehaviorSubject<Model?>(value: nil) var outputNetPop: Observable<Model?> init() { let netOK = inputNet.filter { $0 != nil } outputNetPop = netOK.sample(inputTap) } func click(){ inputTap.onNext(true) } func popUp(net data: Model){ inputNet.onNext(data) }}RxSwift 的 Operator , Sample 具有这个特性 ...

June 4, 2020 · 1 min · jiezi

pod-做了什么子-project-作为动态库三步走

pod 做了什么,子 project 作为动态库 framework,三步走 第一步,添加项目引用: 第二步: 跑一下子 project ,把其 product 作为 framework 第 3 步:把其 product 的 framework,拖入主 project 的依赖 最后,能跑通

June 4, 2020 · 1 min · jiezi

iOS-动画-窗景篇一

iOS 有一种动画,使用虽然简单,但能实现很多有趣的效果,那就是 mask 动画。 如果你还不了解 mask 动画,看完本系列文章后,你可以学会这种动画。如果你已经使用过了,本文也能帮你梳理一下,让你使用起来更方便。 本系列文章共3篇,作为系列的开篇,我们首先要搞清楚一个问题:什么是 mask。 一、什么是 maskmask 是 UIView 或 CALayer 的一个属性,它决定了 view 或 layer 的哪一部分能被我们看到。 本文为了方便讲述,主要使用 view 和它的 mask 属性。iOS 对 mask 的描述,对很多人来说不是特别直观,所以在贴出定义之前,我们先尝试直观地看一下。 首先,我们来看一下这张图: 如图所示,一张纸上有个圆洞,纸盖在了左边的图片上,图片的一部分通过这个洞透了过来,就像墙上开了一扇窗,让我们看到了一部分风景。 不严谨的说,中间的这张黑纸就是 mask,它决定了 view 的哪一部分能被我们看到。 不过这张图会误导我们,让我们感觉 mask 挡住了 view,其实并不是这样。我们来看一下这张图: 从这张图中,我们可以看到:frontView.mask 只影响了 frontView 哪部分可以被我们看到 ,对后面的 backView 没有任何影响。看上去,mask 更像是对 view 进行了裁剪。 上面的两张图并不符合 iOS 对 mask 的描述, 但通过这两张图,我们应该对 “mask 决定了 view 的哪一部分能被我们看到” 这句话,有了直观的印象。 接下来,我们就一起来看一下 iOS 对 mask 的描述。 ...

June 4, 2020 · 3 min · jiezi

赞值得收藏的-iOS-在线资料大全

来源:https://github.com/kechengsou... 发现一个不错的 iOS 资料合(dà)集( quán ),资料非常多,比我之前看到的资料合集要好,排版也比较清晰,还有pdf版可以下载,也有 html 版。 不过貌似项目刚启动(我发现的早~),觉得有用的同学可以去点个 star。 /*** * ┌─┐ ┌─┐ * ┌──┘ ┴───────┘ ┴──┐ * │ │ * │ ─── │ * │ ─┬┘ └┬─ │ * │ │ * │ ─┴─ │ * │ │ * └───┐ ┌───┘ * │ │ * │ │ * │ │ * │ └──────────────┐ * │ │ * │ ├─┐ * │ ┌─┘ * │ │ * └─┐ ┐ ┌───────┬──┐ ┌──┘ * │ ─┤ ─┤ │ ─┤ ─┤ * └──┴──┘ └──┴──┘ * 神兽保佑 * 代码无BUG! */

June 3, 2020 · 1 min · jiezi

iOS-swift-关闭包

一. 闭包表达式(Closure Expression)在Swift中,可以通过func定义一个函数,也可以通过闭包表达式定义一个函数,闭包表达式和闭包是两回事 闭包表达式的格式如下: { (参数列表) -> 返回值类型 in 函数体代码}通过func定义一个函数: func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }通过闭包表达式定义一个函数: //通过闭包表达式定义一个函数,然后调用var fn = { (v1: Int, v2: Int) -> Int in return v1 + v2}fn(10, 20) //闭包调用的时候默认不用写参数名称的 //通过闭包表达式定义一个函数,并且直接调用{(v1: Int, v2: Int) -> Int in return v1 + v2}(10, 20)二. 闭包表达式的简写//传入两个Int变量,返回一个函数func exec(v1: Int, v2: Int, fn: (Int, Int) -> Int) { print(fn(v1, v2))}//什么都不省略exec(v1: 10, v2: 20, fn: { (v1: Int, v2: Int) -> Int in return v1 + v2})//省略参数类型、返回值类型 (因为编译器能推断出来)exec(v1: 10, v2: 20, fn: { v1, v2 in return v1 + v2})//省略returnexec(v1: 10, v2: 20, fn: { v1, v2 in v1 + v2})//超级简写:$0代表第一个参数,$1代表第二个参数exec(v1: 10, v2: 20, fn: { $0 + $1 })//终极简写:只用一个+exec(v1: 10, v2: 20, fn: +)三. 尾随闭包如果将一个很长的闭包表达式作为函数的最后一个实参,使用尾随闭包可以增强函数的可读性。 尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式。 ...

June 2, 2020 · 5 min · jiezi

iOS-NSRunLoop-介绍

来自:https://www.jianshu.com/p/d71... 是什么?RunLoop其实是iOS中的一种消息机制的处理模式。字面的意识就是跑圈,那就是循环了呗。对,就是循环! 理解:学过C语言的同学都知道,每个程序从开始运行到完成需要的计算后打印台打印出你需要的信息后就结束了任务。 那么对于我们的手机来说,任何应用在前台他都是在一直处于运行状态的,随时等待你的命令,对吧!那为什么他在做完你一次的命令任务后退出呢? 这个问题的核心就是RunLoop。 因为RunLoop一直在跑圈啊,一直在循环啊,一直在运行啊,你没有杀死进程啊,So...一直运行着等待你的命令。 作用:保持程序的持续运行处理App中的各种事件(手势、定时器、Selector等)节省CPU资源、提高程序性能:该做任务的时候做任务,没事干的时候休息。理解重点:RunLoop和线程是一对一的关系。比如我们创建项目的时候,刚创建项目的时候就会有个主线程,而这个时候就已经创建了RunLoop了,所以说在线程创建之初就创建了RunLoop(只限于主线程,而子线程需要我们去主动获取),因此线程存在于线程的整个生命周期。 然而好多人问子线程怎么销毁RunLoop? 首先说主线程的RunLoop不能销毁啊,你销毁了程序就退出了。我们现在基本所有应用都用是ARC,我们不需要对内存进行费时的管理,系统会在一个子线程完成的时候销毁掉这个子线程,因此子线程的RunLoop也就跟着自动销毁了。RunLoop对象 在我们开发iOS中有2套API来访问RunLoop Foundation NSRunLoopCore Foundation CFRunLoopRef首先NSRunLoop和CFRunLoopRef都是RunLoop的对象,前者是Oc,后者是C。前者是苹果公司对后者的封装,在正常的开发中NSRunLoop已经够我们使用了,想要了解更多,使用更多,研究更多就去看后者,他是开源的,不过也很难看懂。其实RunLoop底层C都是用一个结构体完成的,里面有各种指针、指针函数、bool值、变量等等等。。。。 RunLoop相关类 RunLoop结构图.png Core Foundation中关于RunLoop的5个类 CFRunLoopRefCFRunLoopModeRefCFRunLoopSourceRefCFRunLoopTimerRefCFRunLoopObserverRef这五个类按照这个结构图一一对应。 CFRunLoopRef代表RunLoop的实体类,一个RunLoop中包含若干个Mode,而每个mode又包含若干个Source/Timer/Observer。 重点: 每次运行RunLoop都必须指定其中一个mode,如果没有mode,RunLoop无法运行,而这个mode被称为当前mode。如果要切换mode,只能退出当前RunLoop,然后再重新指定个mode进入。为什么要像2这样做呢?不是很麻烦吗?苹果这样做是为了区分不同组的Source/Timer/Observer。系统默认的5个modeNSDefaultRunLoopMode 这个mode一般是主线程RunLoop的默认mode。创建线程之初RunLoop是以这种mode运行的。UITrackingRunLoopMode 这个mode是保证滑动ScrollView滑动不受影响,比如滑动tableView的时候主线程就切到这个mode上了。UITInitializationRunLoopMode 在刚启动App的时候第一次进入的mode,启动后就不进入此mode了,本人理解是为了防止App进入时选择了其他mode而运行错乱。GSEventReceiveRunLoopMode 接受系统内部的mode,通常不用。NSRunLoopCommonModes 这个mode是包换1和2的,因此解有个一个问题。定时器触发的时候滑动TableView定时器会停止。这是因为默认是在第一个mode上运行,在滑动的时候RunLoop切换到了第二个mode,所以第一个mode上的任务就被搁置了。 So,解决这个问题就直接把Timer加入到第五个mode中就完美解决了,滑动的时候也不影响定时器的触发。事件源(输入源)Source是事件源也是输入源,比如点击Button按钮、滑动TableView都是一种事件源,告诉RunLoop需要去做什么! CFRunLoopSourceRef分两种: Source0:非基于Port端口,自定义的方法函数、SelectorPerform。简单理解就是你写的就是。Source1:基于Port端口,系统提供默认的方法函数,比如UIApplicationMain。定时器这个就不说了,在上面第五个mode已经说了。 CFRunLoopObserverRefCFRunLoopObserverRef是观察者,能够监听RunLoop所有的状态改变。 可以监听的时间点有如下几种: RunLoopObserver监听的时间点.png 从上往下是: 即将进入RunLoop 即将处理Timer 即将处理Source 即将进入休眠 即将从休眠中被唤醒 即将退出RunLoop 所有状态 这是个枚举,枚举值是2的0次方,1次方,2次方...... 比如在点击按钮的这个操作过程中,RunLoop会把这些状态全部按照任务的顺序走一遍。或者你在滑动,轻扫等操作,RunLoop都会接收到并走这些状态,然后执行任务。 因此有这些状态的判断就可以在好多Oc做不到的地方搞些事情,但是NSRunLoop里面没有提供Observer的这些状态,所以需要用CoreFoundation框架来写 NSRunLoop 结构就是这样的!目前介绍完了。 应用NSRunLoop的应用: 延迟显示ImageView 用RunLoop。(performSelector: withObject: afterDelay: inModes:)这个方法NSTimer。 需要加入mode常驻线程,就是一直让线程活着。其实就是在创建线程的时候,打开当前RunLoop,然后加入mode,然后Run。这个AFNetWorking中也用到了RunLoop(其实是写了个单例创建了一个线程,然后打开RunLoop,加入了mode的SourcePort)把3加入@autoreleasepool中,在runloop睡眠的时候释放。

June 2, 2020 · 1 min · jiezi

几天用Flutter撸了个新浪微博

谷歌在2018年12月正式发布了Flutter,这是一个出色的跨平台框架,可用于移动、桌面和 Web 平台构建应用程序,发布不到一年,它的流行度就超过了React Native以及同领域的产品。从下图就可以看出: 相比其他选项,Flutter有着许多独有的优势。这些优势融入了基础语言和SDK的设计中,以解决其他技术的常见问题和缺陷,简单来说,Flutter的优势主要为以下几个方面:Flutter应用程序可编译为原生二进制文件,在性能表现和流畅的渲染方面,是真正的原生构建应用很难超越的。 除了性能表现之外,Flutter之所以获得如此广泛的使用率,另一大因素就是它提供的出色文档和可供参考的大批高质量示例。 最后,Flutter是基于出色的语言(Dart)和快速的高性能渲染引擎(Skia)从头开始设计出来的,能满足不同技能水平的开发人员基于良好的设计模式和最佳实践来构建应用。 许多开发人员都能够通过Flutter在短时间内创建出高性能的应用程序,这不,前阵子,就有人通过Flutter撸了一个新浪微博,还原微博80%的界面,总共涉及到了几十个界面和接口,用到了Flutter中的大部分组件。 想要学习Flutter的伙伴们可以做一些参考,下面是该项目实现的一些界面: 首页模块: 视频模块: 发现模块: 消息模块: 创建者还给出了相关的一些第三方库: 如果你觉得这个项目对你学习Flutter会有所帮助,就赶紧参考一下吧,最后附上项目地址:github.com/huangruiLea… 面试题持续更新记得关注我哦! 不同的圈子就有不同的学习方式 ; (qq群搜索):651612063 群密码:111 进群文件可以直接获取大厂面试题 推荐点击进群密码:111

May 30, 2020 · 1 min · jiezi

Xcode-Multiple-commands-produce-DerivedData

Multiple commands produce '/Users/.../Library/Developer/Xcode/DerivedData/...方法如下:1:打开菜单栏File,点击Workspace settings2:点击build system3:将build system改为 Legacy Build system

May 27, 2020 · 1 min · jiezi

盘古实验室报告多个-iOS-安全漏洞获苹果官方致谢临时解锁是条件竞争漏洞的重要成因

技术编辑:徐九丨发自 思否编辑部 近日,苹果发布了 iOS/iPadOS 13.5 正式版,新增了 Face ID 增加口罩探测、新冠密切接触追踪等与新冠疫情有关的功能,此外也修复了一些之前的系统 Bug。 但似乎此次的正式版系统仍然存在很多安全问题和漏洞,5 月 26 日,苹果于官网发布了一篇题为《关于 iOS 13.5 和 iPadOS 13.5 的安全报告》的文档公告,详细描述了 iOS 13.5 和 iPadOS 13.5 的安全更新。 据专注于移动互联网安全的「盘古实验室」表示,去年他们在 Black Hat USA 有个议题《Attacking iPhone XS Max》,介绍了如何利用 Unix socket bind 函数中条件竞争导致的 socket UAF 漏洞实现 iPhone XS Max 越狱,并总结到:“临时解锁”是条件竞争漏洞的一个重要成因。 在该基础上,盘古实验室扩大了研究范围,把 XNU 内核中其它 socket 模块也做了分析。基于这个特征,又发现了更多类似的安全漏洞,相继发现内存越界、整数溢出、堆溢出、UAF、多次释放、类型混淆、未初始化变量使用等各种安全漏洞。并从中挑选了十几个典型的漏洞,批量报给了苹果。 此次苹果发布的 iOS 13.5 中对其中的 6 个漏洞进行了修复。 盘古团队是由多名资深安全研究人员组成的专业安全研究团队。团队在主流操作系统和核心软件产品中发现过数百个安全漏洞,因连续多次发布 iOS 完美越狱工具而闻名,是国内首个自主实现苹果iOS完美越狱的团队,也是全球范围内第一个实现针对 iOS 8 和 iOS 9 系统完美越狱的团队。盘古越狱工具被全世界的用户下载数千万次。 ...

May 27, 2020 · 1 min · jiezi

使用-protocol-和-callAsFunction-改进-Delegate指针

2018 年 3 月的时候我写过一篇在 Swift 中如何改进 Delegate Pattern 的文章,主要思想是用遮蔽变量 (shadow variable) 声明的方式,来保证 self 变量可以被常时地标记为 weak。本文中,为了保证没有看过原文的读者能处在同一频道,我会先 (再次) 简单介绍一下这种方法。然后,结合 Swift 5.2 的新特性提出一些小的改进方式。 Delegate简单说,为了避免繁琐老式的 protocol 定义和实现,我们可能更倾向于选择提供闭包的方式完成回调。比如在一个收集用户输入的自定义 view 中,提供一个外部可以设置的函数类型变量 onConfirmInput,并在合适的时候调用它: class TextInputView: UIView { @IBOutlet weak var inputTextField: UITextField! var onConfirmInput: ((String?) -> Void)? @IBAction func confirmButtonPressed(_ sender: Any) { onConfirmInput?(inputTextField.text) } } 在 TextInputView 的 controller 中,检测 input 确定事件就不需要一堆 textInputView.delegate = self 和 textInputView(_:didConfirmText:) 之类 的麻烦事了,可以直接设置 onConfirmInput: class ViewController: UIViewController { @IBOutlet weak var textLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() let inputView = TextInputView(frame: /*...*/) inputView.onConfirmInput = { text in self.textLabel.text = text } view.addSubview(inputView) } } ...

May 27, 2020 · 3 min · jiezi

SwiftUI-Instafilter-基本-UI-和图片导入

构建基本 UI项目的第一步是构建基本的用户接口,对于这个应用来说包括: 一个 NavigationView ,用以在顶部展示应用的名称一个灰色的矩形,显示 “点击以选择图片”,我们导入的图片会放在这里。一个 “强度” 滑块,用来控制应用的 Core Image 滤镜的程度,存储从 0.0 到 1.0 的数值。一个 “保存” 按钮,用来写入修改后的图片到用户的相册。一开始用户还没有选择图片,所以对于图片我们需要用可选的 @State 属性。 首先下面两个属性到 ContentView: @State private var image: Image?@State private var filterIntensity = 0.5复制代码然后修改 body 属性: NavigationView { VStack { ZStack { Rectangle() .fill(Color.secondary) // 显示图片 } .onTapGesture { // 选择图片 } HStack { Text("强度") Slider(value: self.$filterIntensity) }.padding(.vertical) HStack { Button("切换滤镜") { // 切换滤镜 } Spacer() Button("保存") { // 保存图片 } } } .padding([.horizontal, .bottom]) .navigationBarTitle("Instafilter")}复制代码这里有很多的占位符,随着工程的推进,我们逐步填充。 ...

May 26, 2020 · 3 min · jiezi

2020年大厂面试题

1、NSArray与NSSet的区别? NSArray内存中存储地址连续,而NSSet不连续NSSet效率高,内部使用hash查找;NSArray查找需要遍历NSSet通过anyObject访问元素,NSArray通过下标访问2、NSHashTable与NSMapTable? NSHashTable是NSSet的通用版本,对元素弱引用,可变类型;可以在访问成员时copyNSMapTable是NSDictionary的通用版本,对元素弱引用,可变类型;可以在访问成员时copy(注:NSHashTable与NSSet的区别:NSHashTable可以通过option设置元素弱引用/copyin,只有可变类型。但是添加对象的时候NSHashTable耗费时间是NSSet的两倍。 NSMapTable与NSDictionary的区别:同上) 3、属性关键字assign、retain、weak、copy assign:用于基本数据类型和结构体。如果修饰对象的话,当销毁时,属性值不会自动置nil,可能造成野指针。weak:对象引用计数为0时,属性值也会自动置nilretain:强引用类型,ARC下相当于strong,但block不能用retain修饰,因为等同于assign不安全。strong:强引用类型,修饰block时相当于copy。4、weak属性如何自动置nil的? Runtime会对weak属性进行内存布局,构建hash表:以weak属性对象内存地址为key,weak属性值(weak自身地址)为value。当对象引用计数为0 dealloc时,会将weak属性值自动置nil。5、Block的循环引用、内部修改外部变量、三种block block强引用self,self强引用block内部修改外部变量:block不允许修改外部变量的值,这里的外部变量指的是栈中指针的内存地址。__block的作用是只要观察到变量被block使用,就将外部变量在栈中的内存地址放到堆中。三种block:NSGlobalBlack(全局)、NSStackBlock(栈block)、NSMallocBlock(堆block)6、KVO底层实现原理?手动触发KVO?swift如何实现KVO? KVO原理:当观察一个对象时,runtime会动态创建继承自该对象的类,并重写被观察对象的setter方法,重写的setter方法会负责在调用原setter方法前后通知所有观察对象值得更改,最后会把该对象的isa指针指向这个创建的子类,对象就变成子类的实例。如何手动触发KVO:在setter方法里,手动实现NSObject两个方法:willChangeValueForKey、didChangeValueForKeyswift的kvo:继承自NSObject的类,或者直接willset/didset实现。7、categroy为什么不能添加属性?怎么实现添加?与Extension的区别?category覆盖原类方法?多个category调用顺序 Runtime初始化时categroy的内存布局已经确定,没有ivar,所以默认不能添加属性。使用runtime的关联对象,并重写setter和getter方法。Extenstion编译期创建,可以添加成员变量ivar,一般用作隐藏类的信息。必须要有类的源码才可以添加,如NSString就不能创建Extension。category方法会在runtime初始化的时候copy到原来前面,调用分类方法的时候直接返回,不再调用原类。如何保持原类也调用(https://www.jianshu.com/p/40e28c9f9da5)。多个category的调用顺序按照:Build Phases ->Complie Source 中的编译顺序。8、load方法和initialize方法的异同。——主要说一下执行时间,各自用途,没实现子类的方法会不会调用父类的? load initialize 调用时机 app启动后,runtime初始化的时候 第一个方法调用前调用 调用顺序 父类->本类->分类 父类->本类(如果有分类直接调用分类,本类不会调用) 没实现子类的方法会不会调用父类的 否 是 是否沿用父类实现 否 是 9、对 runtime 的理解。——主要是方法调用时如何查找缓存,如何找到方法,找不到方法时怎么转发,对象的内存布局 OC中向对象发送消息时,runtime会根据对象的isa指针找到对象所属的类,然后在该类的方法列表和父类的方法列表中寻找方法执行。如果在最顶层父类中没找到方法执行,就会进行消息转发:Method resoution(实现方法)、fast forwarding(转发给其他对象)、normal forwarding(完整消息转发。可以转发给多个对象) 10、runtime 中,SEL和IMP的区别? 每个类对象都有一个方法列表,方法列表存储方法名、方法实现、参数类型,SEL是方法名(编号),IMP指向方法实现的首地址 11、autoreleasepool的原理和使用场景? 若干个autoreleasepoolpage组成的双向链表的栈结构,objc_autoreleasepoolpush、objc_autoreleasepoolpop、objc_autorelease使用场景:多次创建临时变量导致内存上涨时,需要延迟释放autoreleasepoolpage的内存结构:4k存储大小 12、Autorelase对象什么时候释放? 在没有手加Autorelease Pool的情况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop。 13、Runloop与线程的关系?Runloop的mode? Runloop的作用?内部机制? 每一个线程都有一个runloop,主线程的runloop默认启动。mode:主要用来指定事件在运行时循环的优先级作用:保持程序的持续运行、随时处理各种事件、节省cpu资源(没事件休息释放资源)、渲染屏幕UI14、iOS中使用的锁、死锁的发生与避免 @synchronized、信号量、NSLock等死锁:多个线程同时访问同一资源,造成循环等待。GCD使用异步线程、并行队列15、NSOperation和GCD的区别 GCD底层使用C语言编写高效、NSOperation是对GCD的面向对象的封装。对于特殊需求,如取消任务、设置任务优先级、任务状态监听,NSOperation使用起来更加方便。NSOperation可以设置依赖关系,而GCD只能通过dispatch_barrier_async实现NSOperation可以通过KVO观察当前operation执行状态(执行/取消)NSOperation可以设置自身优先级(queuePriority)。GCD只能设置队列优先级(DISPATCH_QUEUE_PRIORITY_DEFAULT),无法在执行的block中设置优先级NSOperation可以自定义operation如NSInvationOperation/NSBlockOperation,而GCD执行任务可以自定义封装但没有那么高的代码复用度GCD高效,NSOperation开销相对高16、oc与js交互 拦截urlJavaScriptCore(只适用于UIWebView)WKScriptMessageHandler(只适用于WKWebView)WebViewJavaScriptBridge(第三方框架)17、swift相比OC有什么优势? 18、struct、Class的区别 class可以继承,struct不可以class是引用类型,struct是值类型struct在function里修改property时需要mutating关键字修饰19、访问控制关键字(public、open、private、filePrivate、internal) public与open:public在module内部中,class和func都可以被访问/重载/继承,外部只能访问;而open都可以private与filePrivate:private修饰class/func,表示只能在当前class源文件/func内部使用,外部不可以被继承和访问;而filePrivate表示只能在当前swift源文件内访问internal:在整个模块或者app内都可以访问,默认访问级别,可写可不写20、OC与Swift混编 OC调用swift:import "工程名-swift.h” @objcswift调用oc:桥接文件21、map、filter、reduce?map与flapmap的区别? map:数组中每个元素都经过某个方法转换,最后返回新的数组(xx.map({$0 \* $0}))flatmap:同map类似,区别在flatmap返回的数组不存在nil,并且会把optional解包;而且还可以把嵌套的数组打开变成一个([[1,2],[2,3,4],[5,6]] ->[1,2,2,3,4,5,6])filter:用户筛选元素(xxx.filter({$0 > 25}),筛选出大于25的元素组成新数组)reduce:把数组元素组合计算为一个值,并接收初始值() 22、guard与defer guard用于提前处理错误数据,else退出程序,提高代码可读性defer延迟执行,回收资源。多个defer反序执行,嵌套defer先执行外层,后执行内层23、try、try?与try! try:手动捕捉异常try?:系统帮我们处理,出现异常返回nil;没有异常返回对应的对象try!:直接告诉系统,该方法没有异常。如果出现异常程序会crash24、@autoclosure:把一个表达式自动封装成闭包 25、throws与rethrows:throws另一个throws时,将前者改为rethrows ...

May 25, 2020 · 1 min · jiezi