关于objective-c:初探SwiftUI打通任督二脉

序言开年的第一篇文章,明天分享的是SwiftUI,SwiftUI进去好几年,之前始终没学习,所以当初才开始;如果大家还留在 iOS 开发,这们语言也是一个趋势; 目前待业中.... 不得不说已逝的2023年,大家开始都抱着一解封,经济都会向上转好,可是事实不是咱们设想那样;目前我也在学习 SwiftUI,并且致力找工作中....;至于 2024 年经济如何,咱们作为老百姓在大环境和寰球经济影响下;坦然面对,晋升本人。 这里不得不说国人百折不挠的精力。“卷” -- 致力吧Coding人 SwiftUI体验Xcode创立我的项目之后呈现工程默认创立的UI界面;如下 一开始心里对本人说:"SwiftUI作为iOS开发新的UI体系,为啥初创的我的项目这么多代码,给初学者看到,一种压迫感,心想这语法好简单,不想学了";不论你是不是这样心里,我刚开始看见,这么一坨代码,没什么心理,于是索性删掉;按本人能了解学习的形式来操作;于是做了简化: import SwiftUIimport SwiftDatastruct ContentView: View { var body: some View { Text("hello,word”) }}#Preview { ContentView() .modelContainer(for: Item.self, inMemory: true)}关键字 some关键字some啥玩意儿,齐全生疏;先看看View;点击进入源码构造查看: @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)public protocol View { /// The type of view representing the body of this view. /// /// When you create a custom view, Swift infers this type from your /// implementation of the required ``View/body-swift.property`` property. associatedtype Body : View @ViewBuilder @MainActor var body: Self.Body { get }}一堆英文注解预计大家不喜爱看,我就没贴出来了;简略来说:View 是一个泛型协定,它定义了所有视图类型须要遵循的接口,通过some润饰;示意 "我返回一个满足View 协定的某种类型"。some关键字通知 Swift,尽管咱们晓得body必须返回一个View,但咱们不确定具体是哪种 View(例如,Text, Image, VStack 等)。 ...

February 28, 2024 · 4 min · jiezi

关于objective-c:心遇iOS端会话页性能优化-ReactiveObjC实践篇

本文作者:尚尧一、背景心遇作为一款社交产品,音讯会话页必然是用户使用量最大的页面之一,因此会话页的用户体验将尤为重要。同时,心遇有着陌生人社交属性,用户的会话量动辄上万,会话页也面临着较大的性能挑战。因而,会话页的性能优化既是重点,也是难点。 本文将举例会话页已知的性能问题,剖析实现弊病,最初通过引入 ReactiveObjC 来更优雅的解决问题。 二、 ReactiveObjC 简介ReactiveObjC 是一个基于响应式编程 (Reactive Programming) 范式的开源框架了,它联合了函数式编程、观察者模式、事件流解决等多种编程思维,从而让开发者更加高效地解决异步事件和数据流。其外围思路是将事件形象成一个个信号,再依据需要对信号进行组合操作,最初订阅解决信号。通过应用 ReactiveObjC ,写法上由命令式改为申明式,使得代码的逻辑变得更紧凑清晰。 三、实际场景一:会话数据源解决存在的问题问题剖析心遇会话页如图所示: 会话页的数据源来源于 DataSource 。DataSource 保护着一个有序的会话数组,外部监听着各种事件,比方会话更新、会话草稿更新、置顶会话变更等等。当触发事件后, DataSource 可能会从新绑定会话外显音讯、过滤、排序会话数组,最初告诉最上层业务侧刷新页面。结构图如下: 局部实现代码如下: // 会话变更的IM回调- (void)didUpdateRecentSession:(NIMRecentSession *)recentSession { // 更新会话的外显音讯 [recentSession updateLastMessage]; // 过滤非本人家族的会话 [self filterFamilyRecentSession]; // 从新排序 [self customSortRecentSessions]; // 告诉观察者数据变更 [self dispatchObservers];}// 置顶数据变更- (void)stickTopInfoDidUpdate:(NSArray *)infos { self.stickTopInfos = infos; [self customSortRecentSessions]; [self dispatchObservers];}// 草稿箱变更- (void)dartDidUpdate { [self customSortRecentSessions]; [self dispatchObservers];}// 家族数据变更- (void)familyInfoDidUpdate { [self filterFamilyRecentSession]; [self customSortRecentSessions]; [self dispatchObservers];}这里须要解释的是 [recentSession updateLastMessage] 的调用。因为心遇的业务须要,局部音讯是不须要外显到会话页的。因而当收到一条新音讯时,须要从新更新该会话的外显音讯。外显音讯的更新逻辑如下: ...

May 4, 2023 · 2 min · jiezi

关于objective-c:富豪谷底求生纪录片记录

昨天看到知乎推这个主题,十分感兴趣。遂花了一天的工夫把选集看完了(B站有资源),把从中总结到的货色记录了下来。 一共32条,没工夫看全片的同学能够看看上面的总结。 总之我是筹备把这32条背下来了。 ————以下是总结注释———— 1、赚大钱比拟容易,只赚个几百几千,是比拟难的; 2、人一慌乱就容易太早放弃,错失很多机会; 3、建设人脉,建设人脉到底有什么用? (1)货源,卖;(2)能够理解他们为啥做xx生意;(3)找到市场需求;(4)须要人力的时候能够找他们帮忙。4、很多亿万大佬都是从销售做起的,不要瞧不起干销售的 5、要对贵的货色相熟,比如说跑车; 6、有想法要开始口头起来,冷空气并不能阻挡什么; 7、游戏能够当放松的时候玩,不能当花工夫在下面。次要的工夫还应该是求提高; 8、多和富人接触,看他们的纪录片; 9、先找市场,而后找产品去满足 10、五个秘诀 (1)一天的开始要头脑清醒,纵观大局,有喧扰的空间能力成事;(2)先做艰难的事;(3)必然准时赴约——第一印象十分重要;(4)找一个导师,从他们的谬误中吸取教训;(5)绝不投机取巧,否则会造成顾客不满。11、找到一个行业,入行容易不容易被同行打压的 12、明确方向之后,就是要招集能补救本身毛病的人才 13、开始守业的第一步 (1)你要确定理解这一行所有眉角:办法就是真正深刻去这个行业开始做货色(2)能胜利的办法是身边围绕的都是比本人聪慧的人(3)让团队的人置信你,如果他们不置信你,那么你什么都做不成;(4)要打造品牌,他人一看到某个中央,就想到某个产品14、永远别让人看到你缓和;你要放弃沉着,把握住底线 15、永远不要得意洋洋,不因挫折低沉,然而小的胜利十分重要。 16、守业胜利的一点是找到各行业的专家 17、练习谈话,要读书、演讲,有煽动性。 18、治理团队时激励一个人不须要当面和他谈激励他,只有散会时把优秀员工的体现进去,看看他的反馈就行了,如果反馈不好,那可能就是找错人了。 19、领导者有不同的风格 (1)也就是心愿员工感觉是我为他们做事,把想法反馈给他;(2)"我就晓得设个时限,让你自由发挥会胜利的"20、要乐观,也要思考事件的结果:每次都感觉本人要失败了 21、化敌为友是最好的办法; 22、做leader有时候有些业余货色不是很理解,然而也肯定要硬气的说,说完之后再转给上司来说。 23、要找好的员工,如果没有适宜的职位,能够为他发明一个职位; 24、删掉过多的音讯,分明阐明需要,从头到尾把握要点; 25、做领导不是为了给团队压力,而是为了让他们明确,只有把事件干成了,团队每个人的付出才有意义; 26、致力的时候也要打造本人的品牌; 27、不要坐等良机落入手中,没有那么好的事; 28、举例:如果有一个员工给你汇报工作的时候没有实现,那你作为领导者应该怎么办? (1)回复:让你来负责这部分内容,代表你就是领导者而不是员工,作为领导者要积极主动。你没有问我想要什么样的格调,没有问我进度如何,没有用狠劲来问我到底该怎么做,而是坐等我的安顿。我卖房子、找烧烤师、找店铺,有千百万事件要做,所以事关你的工作的,你要全权处理。你想要胜利就要当个斗牛犬,这是不二法门。我敢保障百分百被动的人不会胜利。要么回公司下班,要么拿出狠劲来。这是你该做的事。(2)形象模板 【1】表明员工的重要性;【2】说我作为领导者有多忙;【3】形象鸡汤教诲;【4】最初说下冀望的后果,也就是心愿胜利。<<<< 领导的形象能力要很强。29、要多问有意义的问题,最简略的办法就是问形象的问题 30、口头前要做好查看; 31、再难再缓和都要放弃微笑,你能够向员工说本人很缓和,然而肯定要放弃笑容。语言表达进去即可,不要用表情来裸露你的心田。举个例子:你在很缓和的时候给员工说当初的状况,如果100米之外听不到你谈话的人也从你的表情中看出你很慌乱,和平时不一样,那么这就不是合格的表情治理。 32、不要发脾气,这个领导不发脾气,也不让员工发脾气; (1)原话是:局面难看的时候,不要随之起舞,压力下能不能放弃沉着正式业余与否的差异。

April 10, 2022 · 1 min · jiezi

关于objective-c:经济机器如何运转笔记

视频链接:【Ray Dalio】三十分钟看懂经济机器如何运行(比尔盖茨举荐) 影响经济的三要素 生产率的进步短期债权周期长期债务周期了解交易每次交易中:买方应用 货币/信用 向卖方获取 商品、服务或股票资产 收入总额 = 货币 + 信用 收入总额是经济的驱动力 价格 = 收入总额 / 销量 所有的经济周期和能源都是交易造成的。 市场收入总额 / 产销总量 ,就失去了理解经济市场的全副信息 信贷是经济中最重要的组成部分。 信贷产生债权,债权是贷款人的资产,是借款人的负债。 为什么借贷如此重要?因为借款人获取信贷后,能够减少收入,收入是一个经济的驱动力,一个人的收入就是另一个人的支出。 因为一个人的收入是另外一个人的支出,当一个人的支出减少时,银行违心贷更多的钱给借款人。 也正是因为如此,才产生了经济周期。 生产率在长期内最要害,但信贷在短期内最重要。 债权能够让购买时,生产高于产出,但在还债时不得不让 生产低于产出。 债权稳定有两大周期: 小周期:5-8年大周期:75-100年 如果没有信贷的生存是怎么样的? 没有信贷时,收入等于支出,如果想收入更多,那么就须要进步生产率,进行翻新或者进步工作量。 信贷的实质是向将来的本人借钱,将来你的收入肯定要小于支出,以便偿还债务,于是便人为的制作了一个周期: 现实生活中,大部分的钱实际上就是信贷,美国国内的信贷总额大概为50万亿美元,而货币总额只有大概3万亿美元。 短期债权周期信贷容易取得,大家就会取得更多的钱,但社会产出是肯定的,就会导致通用收缩。 反之就会导致通货紧缩: 长期债务周期消退能够通过降低利率来调节,但去杠杆化无奈应用降低利率调节,因为利率曾经非常低了: 贷款人进行放贷,借款人进行借贷。 如何应答去杠杆化呢? 削减收入缩小债权:债权重组财产再调配:富人转给富人发行货币只有衡量好这4个步骤,能力谐和的去杠杆化。 央行能够减少货币发行量,来补救隐没的信贷。 总结不要让债权的增长速度超过支出不要让支出的增长速度超过生产率:因为这最终将会使你失去竞争力,本人的价值配不上工资就会被裁员。尽所有努力提高生产率

April 10, 2022 · 1 min · jiezi

关于objective-c:3天时间从零到上架AppStore流程记录

3天工夫从零到上架AppStore流程记录清明假期刚过去一周,我如愿以偿把本人想要的一个App上架了AppStore 从有idea到技术选型,从设计稿到框架开发,从提审AppStore到上架一共经验了3天,这3天里我踩了很多坑,忙得焦头烂额,期间发现网上很多信息都是过期的,所以本着一个总结的想法,写了这篇文章。 一、idea到设计稿(一)idea灵感起源平时我下班很忙,休闲时会刷手机看B站、Youtube视频,但因为平时关注了太多人,想看的却只有那几个,但还是会忍不住点击算法举荐的视频。 "xdm洁净又卫生啊""大佬别这样""守护每一个不切实际的幻想"B站内容丰盛,每次不仅看不到想看的视频,反而花了比预计好几倍的工夫。 所以我想要做一个产品,喜爱可能帮我追踪B站、Youtube平台上我最想关注的人的动静,不必我每次关上B站、Youtube去查看内容,所以我依照素日工作里排期的流程给本人做了性能的排期: - 喵酱爱订阅 - 展现导航栏 - 搜寻页面 - 写搜寻的cgi - 写解析用户状态的cgi - 要反对右滑勾销订阅 - 把用户状态数据更新到缓存 - 把缓存落到DB - 每次启动读取DB - 制作宣传视频 - 制作启动教育页 - 分割页 - 分割跳转等页面 - 性能优化 - 加一个by xxx 关注,而后谈起一个半屏 - 加一个 xx、yy和另外x人关注了此账号 - 须要退出loading等逻辑 - 全局extension call:按id注册,还是全副接管 - 开始更新订阅数据- 搜寻页面 - 呈现导航栏 - 呈现敞开按钮 - 点击搜寻要能过渡到另外一个搜寻界面 - 开始接B站搜寻的api - 开始实现订阅该Up主性能 - 滑动删除 - 搜寻交互调整- 订阅数据 - 开始更新订阅数据,获取更全的信息 - 按timeline排序接下来要做的: - 反对Youtube订阅 - 实现B站跳转逻辑 - 实现Youtube跳转逻辑 - 实现清理红点逻辑 - 调整搜寻两头页逻辑 - 「对于」页面设计 - 帮忙和常见问题 - 隐衷政策 - 视觉还原和调整(增加束缚) - 增加主页元素的联动束缚 - 主页下滑不到最底部 - 导航栏色彩问题 - 修bug - 订阅完之后,不会立即呈现 - Youtube API有限调用 - App选一个图标(二)本人搞定设计稿有了idea之后,依照正经开发流程,相当于是产品计划确定了,接下来就须要设计稿了。 ...

April 9, 2022 · 3 min · jiezi

关于objective-c:Swift怎样使用OC枚举多个枚举以及OC多枚举实现

前段时间我同学写的OC版本的SDK给第三方用,第三方用Swift写的我的项目,不会应用Swift去调用OC的枚举,起初我同学找到我,我就给他写了一下,废话不多说,间接上代码。 OC枚举:typedef NS_ENUM(NSInteger, SwiftUseOCEnum) { SwiftUseOCEnumNone = 1<<0,SwiftUseOCEnumOne = 1<<1,SwiftUseOCEnumTwo = 1<<2,SwiftUseOCEnumThree = 1<<3,}; @interface Test : NSObject -(void)test:(SwiftUseOCEnum)ocEnum; @end OC枚举多枚举实现:-(void)test:(SwiftUseOCEnum)ocEnum{ if(ocEnum == SwiftUseOCEnumNone){ NSLog(@"SwiftUseOCEnumNone");}else if (ocEnum == SwiftUseOCEnumOne) { NSLog(@"SwiftUseOCEnumOne");}else if (ocEnum == SwiftUseOCEnumTwo) { NSLog(@"SwiftUseOCEnumTwo");}else if (ocEnum == SwiftUseOCEnumThree) { NSLog(@"SwiftUseOCEnumThree");}else{ //传了多个枚举进来 if((ocEnum & SwiftUseOCEnumNone) == SwiftUseOCEnumNone){ NSLog(@"多个枚举蕴含了SwiftUseOCEnumNone"); } if((ocEnum & SwiftUseOCEnumOne) == SwiftUseOCEnumOne){ NSLog(@"多个枚举蕴含了SwiftUseOCEnumOne"); } if((ocEnum & SwiftUseOCEnumTwo) == SwiftUseOCEnumTwo){ NSLog(@"多个枚举蕴含了SwiftUseOCEnumTwo"); } if((ocEnum & SwiftUseOCEnumThree) == SwiftUseOCEnumThree){ NSLog(@"多个枚举蕴含了SwiftUseOCEnumThree"); }}} ...

March 30, 2022 · 1 min · jiezi

关于objective-c:RGBYUVHSV和HSL区别和关联

RGB、YUV、HSV和HSL区别和关联近期在做的一个需要和色彩转换有关系,所以本篇将开发过程中比拟常见的 四种色彩 进行一番梳理。 一、RGB色彩空间从咱们最常见的RGB色彩登程,RGB别离对应着 Red(红)、Green(绿)、Blue(蓝),也就是咱们平时所说的三原色,调整这三种色彩的比例,能够搭配出所有的色调。 这时你可能就要问了,YUV、HSV、HSL也能形容所有色调啊,为啥RGB是最罕用的捏? 这就要回归到事实了,事实里显示器显像时,每一个像素点前面对应着 3个发光二极管,这3个二极管能够别离收回 红、绿、蓝 三种色彩,因而绝大部分人所能接触的色彩只与RGB有关系。 RGB(红绿蓝)是根据人眼辨认的色彩定义出的空间,可示意大部分色彩。但在科学研究个别不采纳RGB色彩空间,因为它的细节难以进行数字化的调整。它将色调,亮度,饱和度三个量放在一起示意,很难离开。它是最通用的面向硬件的黑白模型。该模型用于黑白监视器和一大类黑白视频摄像。 二、YUV色彩空间YUV 多呈现在音视频合成畛域,音视频合成畛域要求在表白同样内容时,争取占用更少的空间。同个视频,YUV空间要比RGB空间描述省下来一半的空间耗费(YUV4:2:0)。 YUV(也称:YCbCr):Y示意亮堂度,UV的作用是形容影像色调及饱和度。 次要的采样格局有 YUV4:2:0(最罕用)、YUV4:2:2 和 YUV4:4:4 ,也就是说 RGB 次要用于屏幕图像的展现,而 YUV 多用于采集与编码。 YUV 和 RGB 互相转换的公式为: 三、HSV(HSB) 和 HSL能够发现 RGB 次要为硬件显示器服务,YUV 次要为音视频编解码服务,这么说下来和色调最密切的 设计师 该用哪种颜色呢? 他们也有本人行业特地关注的色彩,次要应用 HSV 和 HSL。 (一)为什么RGB不适用于图像处理人眼对于RGB这三种色彩重量的敏感水平是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 色彩空间是一种平均性较差的色彩空间。如果色彩的相似性间接用欧氏间隔来度量,其后果与人眼视觉会有较大的偏差。对于某一种色彩,咱们很难揣测出较为准确的三个重量数值来示意。 简略来说,如果计算不同色彩之间的对比度,如果应用 RGB 来计算: (R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2 即便两组色彩数值雷同,人的感触还是不一样的,比方这里我选三个色彩: RGB_1:110,0,110RGB_2:60,0,100RGB_3:160,0,110 能够看到只管 RGB_1 和 RGB_3 间隔 RGB_2 计算的欧式偏差是一样的,但咱们还是会显著感觉 RGB_1 相比 RGB_3 更靠近 RGB_2 ,因为 RGB_3 看上去比 RGB_1 和 RGB_2 更亮一些。 ...

March 20, 2022 · 6 min · jiezi

关于objective-c:CPU是海王聊聊-主子线程-和-同异步-的关系

最近表弟始终在找实习,常常会问我一些问题,有些问题在没有经验过实在工作时是真的不好了解的,所以我开了这个【表弟专栏】,专门为找工作的表弟解决一些纳闷。这篇文章从计算机倒退的角度登程,形容为什么计算机须要划分 "主/子线程" 和 "同/异步",心愿这个故事你能喜爱。 开天辟地,计算机"老计"诞生话说几十年前,老计(初代CPU)诞生了,老计诞生初期帮人们解决了诸多繁琐的计算工作,他能够无休无止地依照人们给的指令进行运算。 就像图中一样,人们产生着各种问题,而后把问题丢入到一个队列中去,老计依照人们丢入的指令按程序进行计算。 但就像当初互联网越来越卷一样,老计工作几年之后,发现要做的事件切实是太多了,有些计算要算完要搞到几十年后了,这可咋办呢? 这时人们认为老计该退休了,换了大计出场,大计的长处是相当卷,计算速度是老计的N倍,大大晋升了计算的速度。 事实问题,大计海王进化(主/子线程)大计有一天在诚诚恳恳工作时,被主管拉到了办公室,开始批评大计: "大计啊,我晓得你工作起来很致力,但你有点死板了啊,所有人给你调配的工作你都是按程序操作,导致用户说咱们的产品就像在挤牙膏,一点点挤出来。你能再放慢工作速度吗?不能只靠加班来实现工作啊!" 大计一脸mmp像,心想:“我特么要做什么,不还是你给到的指令啊”,但大计有着当代互联网人独特的指标("保住这份工"),所以大计也只能说: "好的主管,这事我想想方法,今天给你个回答。" 大计这天工作到凌晨3点,上班后和总线一起去喝酒,说起了白天被主管叼这件事,总线说: "这事好办啊,我平时给你传的各种指令,优先级不高的你让它不要走同一条门路传输呀,咱们像渣男一样搞个高并发!给每个指令都送去和煦,钓住她们,让她们认为你是专一的男人,实际上你在同时和多人来往。" 大计一听直呼妙计妙计,总线不愧是和各个部门打交道的社交花,把泡妞能力用到工作上间接无缝连接。 之前大计只有一条指令流水线时,他是按走流程,指令1解决完了,才解决指令2,是一个对指令专一的女子。 大计当即画出了这样的指令图: 大计当初能"同时"解决 3条指令:M_0、A_0和B_0,说是"同时",实际上只是大计在这三条指令里频繁切换,M_0实现40%,就去招呼下A_0,A_0解决完80%后,而后再去招呼下B_0指令。 也就是说尽管工作时长是肯定的,但给主管一种同时在解决3个指令的错觉。就靠着这套海王策略,大计终于实现了刁钻主管的需要。 不急的话,这事能够等等再做(同/异步)随着大计海王能力的扩大,当初最高时能够"同时"和几百个指令妹子约会,曾经是不可被代替的重要角色,当初主管每天看到大计都得磕个头,大计的话语权也越来越大,甚至开始反过来给主管提需要了: "主管啊,你可要晓得我主线程是负责和用户交互的重要线程啊,你每天在主线程丢那么指令,十分影响用户的体验了啊" "你有些渲染UI的逻辑太频繁了,导致我做了很多无用的渲染,而且渲染逻辑也分重要水平啊,不重要的指令你等我闲暇了再解决啊" 主管连连拍板,说好的好的:"咱们下次增加指令时,会通知你这个指令是否须要立即施行,如果不那么重要能够等你闲暇下来再解决。" 于是乎,同步、异步 的概念诞生了: 之前大计在解决 主线程 里的指令时,因为同一个线程指令是没有优先级的概念的,所以 线程里的指令还是按程序解决的:M_0 -> M_1 -> M_2 -> M_3 -> M_4 但有了 异步 的概念后,假如这里的 指令M_1 不那么重要,那么大计在解决时是能够把 M_1 放到前面解决的:M_0 -> M_2 -> M_3 -> M_4 -> M_1 小结本篇【表弟专栏】给大家聊了 主/子线程 诞生的必要性,形容了CPU海王实质,以及和同/异步的区别和关联。对于 主/子线程 和 同/异步 的问题,大家能够在评论区一起探讨。最初如果大家喜爱这个专题,能够关注我的公众号:冰以东,会继续更新【表弟专栏】,心愿能帮忙大家找到更好的工作。

March 19, 2022 · 1 min · jiezi

关于objective-c:SourceTree代码变更和FoxMail邮件管理效率小计俩

代码变更溯源工作时,咱们常常会想要查看一个类文件的变更历史,最常见的场景是:"卧槽,谁改了我的代码" 新版本的Xcode溯源自我感觉相当难用,所以这里咱们介绍一个工具 SourceTree 来实现这项工作。 将我的项目工程加载到 SourceTree当咱们把我的项目工程拖到 SourceTree 之后,能够看到如下的内容: 其中BNBitcoinIndexApp是我的我的项目工程名。 检索文件抉择 ①文件状态 -> ②搜寻文件 -> ③查看选中的批改日志 查看文件变更如此能够看到所有改变到该文件的commit(是按工夫顺序排列)。 邮件治理公司会发几十封、多的时候上百封邮件,邮箱被各种咱们不关怀的邮件塞满,慢慢地有价值的邮件也会被咱们疏忽。 这时咱们学会对邮件进行治理,邮件治理分为两个步骤:首先是对邮件进行分类,其次是对邮件进行规定过滤。 邮件组 点击 Foxmail -> 新建文件夹,假如你对专利比拟感兴趣,能够新建文件夹专利相干: 邮件过滤这里咱们应用 Foxmail 自带的 规定匹配: 任意右键点击一封右键,而后抉择 创立规定,创立如下的规定: 点击利用到历史邮件,稍等加载一会咱们的邮件分组就实现了:

March 19, 2022 · 1 min · jiezi

关于objective-c:SpringBoot架构关键词全解

一、外围配置文件一个我的项目中 application.yml 和 application.properties 只能有一个。 (一)application.properties# 设置内嵌Tomcat端口号server.port = 8081#设置上下文根server.servlet.context-path = /springboot(二)application.ymlYML文件格式是YAML (YAML Aint Markup Language)编写的文件格式,YAML是一种直观的可能被电脑辨认的的数据数据序列化格局,并且容易被人类浏览, 容易和脚本语言交互的,能够被反对YAML. YML文件是以数据为外围的,比传统的xml形式更加简洁。 server: port: 8081 servlet: context-path: 二、获取SpringBoot自定义配置的字段(一)通过 @Value 注解读取自定义配置字段配置 application.properties # 设置内嵌Tomcat端口号server.port = 8081#设置上下文根server.servlet.context-path = /springbootschool.name = binSchoolwebsit=http://bninecoding.com应用 @Value("${school.name}") @Value(${school.name})private String schoolName;(二)将自定义配置映射成对象波及注解: @Component // 将此类交给spring容器进行治理@ConfigurationProperties(prefix = "school")@Autowired配置 application.properties server.servlet.context-path = /springbootschool.name = binSchoolschool.websit = binSchoolabc.name = binSchoolabc.websit = binSchool创立 school 类: @Component@ConfigurationProperties(prefix = "school")public class School { private String name; private String websit; public String getName() { retutrn name; } public void setname(String name) { this.name = name; } ...}因为@Component这样做之后曾经将 school 类加载到 spring 容器里了,所以应用时能够应用 @Autowired 注入进来: ...

March 13, 2022 · 3 min · jiezi

关于objective-c:操作数据库你不得不知道的-事务-理念

无论是 iOS操作DB、还是 SpringBoot中Service操作Mybatis,都须要波及到 事务 的概念,如果你在新增一个 DB 增删改 的接口时,没有思考到事务,那么你新增的接口肯定是有问题的。 了解事务事务是指对系统进行的一组操作,为了保证系统的完整性,事务须要具备ACID个性,具体如下: 1. 原子性(Atomic)一个事务蕴含多个操作,这些操作要么全副执行,要么全都不执行。实现事务的原子性,要反对回滚操作,在某个操作失败后,回滚到事务执行之前的状态。 回滚实际上是一个比拟高层形象的概念,大多数DB在实现事务时,是在事务操作的数据快照上进行的(比方,MVCC),并不批改理论的数据,如果有错并不会提交,所以很天然的反对回滚。 而在其余反对简略事务的零碎中,不会在快照上更新,而间接操作理论数据。能够先预演一边所有要执行的操作,如果失败则这些操作不会被执行,通过这种形式很简略的实现了原子性。 2. 一致性(Consistency)一致性是指事务使得零碎从一个统一的状态转换到另一个统一状态。事务的一致性决定了一个零碎设计和实现的复杂度。事务能够不同水平的一致性: 强一致性:读操作能够立刻读到提交的更新操作。弱一致性:提交的更新操作,不肯定立刻会被读操作读到,此种状况会存在一个不统一窗口,指的是读操作能够读到最新值的一段时间。最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保障在没有其余事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有谬误产生,不统一窗口的大小依赖于:通信提早,零碎负载等。其余一致性变体还有: 枯燥一致性:如果一个过程曾经读到一个值,那么后续不会读到更早的值。会话一致性:保障客户端和服务器交互的会话过程中,读操作能够读到更新操作后的最新值。3. 隔离性(Isolation)并发事务之间相互影响的水平,比方一个事务会不会读取到另一个未提交的事务批改的数据。在事务并发操作时,可能呈现的问题有: 脏读:事务A批改了一个数据,但未提交,事务B读到了事务A未提交的更新后果,如果事务A提交失败,事务B读到的就是脏数据。不可反复读:在同一个事务中,对于同一份数据读取到的后果不统一。比方,事务B在事务A提交前读到的后果,和提交后读到的后果可能不同。 不可反复读呈现的起因就是事务并发批改记录,要防止这种状况,最简略的办法就是对要批改的记录加锁,这回导致锁竞争加剧,影响性能。另一种办法是通过MVCC能够在无锁的状况下,防止不可反复读。幻读:在同一个事务中,同一个查问屡次返回的后果不统一。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查问操作,发现后一次比前一次多了一条记录。 幻读是因为并发事务减少记录导致的,这个不能像不可反复读通过记录加锁解决,因为对于新增的记录根本无法加锁。须要将事务串行化,能力防止幻读。事务的隔离级别从低到高有: Read Uncommitted:最低的隔离级别,什么都不须要做,一个事务能够读到另一个事务未提交的后果。所有的并发事务问题都会产生。Read Committed:只有在事务提交后,其更新后果才会被其余事务看见。 能够解决脏读问题。Repeated Read:在一个事务中,对于同一份数据的读取后果总是雷同的,无论是否有其余事务对这份数据进行操作,以及这个事务是否提交。 能够解决脏读、不可反复读。Serialization:事务串行化执行,隔离级别最高,就义了零碎的并发性。 能够解决并发事务的所有问题。通常,在工程实际中,为了性能的思考会对隔离性进行折中。 4. 持久性(Durability)事务提交后,对系统的影响是永恒的。 示例举一个近期开发过程中遇到的例子: 珍藏音乐的业务,有一个 songID(音乐id) 和 localId(珍藏生成的id)在咱们珍藏一首音乐时:>> 步骤1:首先须要将 songId 和 localId 的映射关系存到 映射DB>> 步骤2:接着能力将 音乐 存到珍藏业务里。如果步骤1失败了,那就肯定不能执行步骤2,同理,如果步骤2失败了,也要同步回滚掉步骤1的数据。也就是说:整个珍藏业务肯定是 事务型的。文章首发:问我社区

March 13, 2022 · 1 min · jiezi

关于objective-c:编写第一个GETPOST接口renrenfast框架系列1

配置好 renren-fast 脚手架,学习完 Spring MVC 架构后,我须要具体调试 renren-fast 的接口,比方要新增某个接口。 什么是前后端拆散运行 renren-fast 我的项目时,咱们拜访 http://localhost:8080/renren-... 的后果: 能够看到,接口给出了相应的回应,状态码 401 Unauthorized 代表客户端谬误,指的是因为不足指标资源要求的身份验证凭证,发送的申请未失去满足。 运行 renren-fast-vue 我的项目时,咱们拜访 http://localhost:8001/#/login : 接着应用Chrome自带的网络工具: 点击 Headers 能够查看 Request URL: 以此,咱们确认拜访 后盾接口为:http://localhost:8080/renren-... 同时还能够看到如下获取页面信息的 headers: 申请的拜访接口是:http://localhost:8001/static/... 至此,咱们便搞清楚了 renren-fast 前后端拆散的业务是在说什么,即:后端逻辑应用 renren-fast 实现,前端申请获取的页面数据,应用 renren-fast-vue 实现。 写一个无需鉴权的GET接口接下来咱们基于 renren-fast 框架仿照 "/captcha.jpg" 写第一个接口, "/captcha.jpg"接口代码: /** * 验证码 */ @GetMapping("captcha.jpg") public void captcha(HttpServletResponse response, String uuid)throws IOException { response.setHeader("Cache-Control", "no-store, no-cache"); response.setContentType("image/jpeg"); //获取图片验证码 BufferedImage image = sysCaptchaService.getCaptcha(uuid); ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, "jpg", out); IOUtils.closeQuietly(out); }咱们写一个 /testInterface 接口,在没写接口之前,咱们拜访: http://localhost:8080/renren-... ,返回如下款式: ...

March 13, 2022 · 1 min · jiezi

关于objective-c:时序控制和引用计数理念

明天在听一个T10的问难,其中有一个理念让我觉得很有意思,记录一下。 背景: 下载视频业务层均应用Service,同一个下载工作只能对应一个播放行为。如果两个业务依照如下程序下载同一个视频,就会呈现问题: 最后听到这个问题,我第一想到的计划是代码管制时序,在业务B前查看业务A,保障调用业务B时,A的业务曾经停掉了。 但这样的解决形式仅仅是为了解决以后问题给出的计划,如果后续有业务C、业务D也遇到相似的状况,那还是须要非凡解决。 问难的同学给出的一个计划很简略,但很有意思: 它对播放器做了援用计数的逻辑,只有援用计数归零了,才会彻底移除下载工作。 援用计数咱们熟记于心,但能想到用这种计划解决问题的,我感觉很牛逼。 **这个公众号会继续更新技术计划、关注业内技术动向,关注一下老本不高,错过干货损失不小。↓↓↓**

March 9, 2022 · 1 min · jiezi

关于objective-c:打造高可用iOS进度条

前言做全屏的需要时,因为进度条会从半屏背景下的「根本不可能曝光」,变成全屏场景下「高频曝光」,所以须要打造一个丝滑、高可用的进度条,想当初我Debug到凌晨4点,就是为了解决暂停后进度条的动画问题。 明天把这个进度条的架构、设计逻辑和踩过的坑都整顿一下。 本文波及的代码已开源至Github:打造高可用进度条 接口介绍BNCommonProgressBar.h// 变更进度,animateWithDuration是传入动画工夫- (void)setValue:(CGFloat)value;- (void)setValue:(CGFloat)value animateWithDuration:(NSTimeInterval)duration time:(NSTimeInterval)time;- (void)setValue:(CGFloat)value animateWithDuration:(NSTimeInterval)duration completion:(void (^__nullable)(BOOL finished))completion;// 重置所有状态,会将进度重置到0- (void)reset;// 暂停动画- (void)pauseAnimation;// 复原动画- (void)resumeAnimation;// 清理动画状态,手动拖拽时先清理动画状态- (void)removeProgressAnimation;一、为什么 UISlider 不满足「高可用」的指标?在论述 UISlider 不满足「高可用」指标之前,咱们先思考一下,满足什么样的条件的进度条,才能够算是「高可用」? 我想出四个指标: UI可高度定制晦涩的回调动画可定制的响应范畴响应手势,且无卡顿问题其中 UISlider 可满足其中 3 和 4,因为 UISlider 是零碎提供的组件,「UI可高度定制」这条必定不满足。 且 UISlider 对于动画的解决不够弱小,在视频播放的场景下,视频播放器会定时高频的回调视频播放进度,更新进度的动画要足够晦涩,但实际上应用 UISlider 的成果是上面这样的: 所以 UISlider 不满足 第2点:「晦涩的回调动画」,而视频号场景下,视频进度回调更新进度条进度是高曝光的场景,肯定要把这个动画做得足够晦涩。 在这样的背景下,放弃 UISlider ,自定义进度条是惟一的抉择。 二、定制一份「高可用」进度条Tips:BNCommonProgressBar是咱们定制的进度条的类名,首先先看一下BNCommonProgressBar实现的成果: BNCommonProgressBar 设计与需要绝对应: 指标:UI可高度定制 --> 计划:自定义UI指标:晦涩的回调动画 --> 计划:动画解决指标:可定制的响应范畴 --> 计划:手势范畴解决指标:响应手势,且无卡顿问题 --> 计划:拖拽手势解决,卡顿问题解决所以 BNCommonProgressBar 的设计也就分为 4个模块。 (一)自定义UIBNCommonProgressBar初始化办法为: - (instancetype)initWithFrame:(CGRect)frame barHeight:(CGFloat)progressBarHeight dotHeight:(CGFloat)dotHeight defaultColor:(UIColor *)defaultColor inProgressColor:(UIColor *)inProgressColor dragColor:(UIColor *)dragColor cornerRadius:(CGFloat)cornerRadius progressBarIconImage:(UIImage *)progressBarIconImage enablePanProgressIcon:(BOOL)enablePanProgressIcon;容许业务层配置进度条高度、进度圆点高度、默认色彩、处于进度拖拽时的色彩、是否容许拖拽等,相比 UISlider 有更高的自定义水平。 ...

March 9, 2022 · 2 min · jiezi

关于objective-c:使用-Hexo-Github-搭建博客

始终想搭建属于本人的博客,用来记录本人的所学。 但都因为各种各样奇怪的工夫安顿搁置了,导致我甚至开始用起了公司的git工具记录知识点.. 明天终于把博客搭建结束,顺便也把搭建博客路上遇到的坑记录下来。 先备常识(一)应用 Hexo & Github 搭建博客的起因首先,咱们思考一下,相比间接把内容发在 简书/掘金 平台上,自建博客有什么劣势? 通过本人的域名能够拜访博客,不必放心平台跑路/保护危险能够本人抉择博客款式本人的博客相当于本人的一份名片,通过优化SEO能够做到很好的扩充影响力的成果。当初搭建博客能够有N多工具,比方:买腾讯云服务器搭建博客、应用Jelly配置又或者本人自建网站。 但以上流程对于只是想领有一份记录本人所学的博客需要来说,工夫老本和收入老本都是偏高的。 Hexo 能够让咱们便捷地搭建博客,应用别人曾经设计好的博客模板;github的pages性能能够为咱们提供收费的服务器,让咱们零老本搭建属于本人的博客。 便捷、低成本、扩展性好 就是采纳 Hexo & Github 的次要起因。 (二)username/nickname On Github要辨别要 github 上 username 和 nickname 的区别,这点在搭建博客时十分重要 (三)配置 Hexo要配置好 Hexo ,此外理解肯定的 nodeJs 根底能够让你更分明你在配置过程中都在做什么,而不是只跟着教程操作而已,比方 npm install 是在做什么、以及为什么 package.json 能够很便捷地关联库的起因等等。 (四)命令行操作工具有肯定的命令行操作根底,能灵便应用 iTerm ,相熟 git 语法更佳。 (五)辨别 brew、npm、pip、apt-get 指令。这四个指令实际上是 不同零碎下治理软件包的指令。 一、brew即Homebrew,是Mac OSX上的软件包管理工具,能在Mac中不便的装置软件或者卸载软件, 只须要一个命令。默认都是装置到brew的指定目录“/usr/local/Cellar”下,而后在“/usr/local/bin”下创立对应的软连贯来应用的。如果装置多个不同版本的库,能够批改对应的软连贯就能够了二、npm(全称Node Package Manager,即“node包管理器”)是Node.js預設的、用JavaScript編寫的軟體套件管理系統。三、pippython软件包管理系统,能够利用它装置python包,默认都装置到以后python版本的python3.7/site-packages文件夹下四、apt-getlinux命令,实用于deb包治理式的操作系统,次要用于主动从互联网的软件仓库中搜寻、装置、降级、卸载软件或操作系统(六)理解 hexo 指令的含意比方 hexo init 、hexo d -g 、hexo s。 搭建博客流程(一)应用 github pages 创立繁难博客1. 在github建设博客仓库首先在本人的 github 上创立一个仓库,命名为 : username.github.io ...

March 9, 2022 · 1 min · jiezi

关于objective-c:iOS编译过程的原理和应用

浏览本文你将播种: iOS编译流程明确 __text、__data 的含意iOS dSYM 的作用和生成形式明确iOS crash堆栈符号化解析流程source: iOS编译过程的原理和利用 iOS 如何调试第三方统计到的解体报告 iOS Link Map File 文件阐明 前言个别能够将编程语言分为两种,编译语言和直译式语言。 像C++,Objective C都是编译语言。编译语言在执行的时候,必须先通过编译器生成机器码,机器码能够间接在CPU上执行,所以执行效率较高。 像JavaScript,Python都是直译式语言。直译式语言不须要通过编译的过程,而是在执行的时候通过一个两头的解释器将代码解释为CPU能够执行的代码。所以,较编译语言来说,直译式语言效率低一些,然而编写的更灵便,也就是为啥JS大法好。 iOS开发目前的罕用语言是:Objective和Swift。二者都是编译语言,换句话说都是须要编译能力执行的。二者的编译都是依赖于Clang + LLVM. 篇幅限度,本文只关注Objective C,因为原理上大同小异。 可能会有同学想问,我不懂编译的过程,写代码也没问题啊?这点我是不否定的。然而,充沛了解了编译的过程,会对你的开发大有帮忙。本文的最初,会以以下几个例子,来解说如何正当利用XCode和编译 __attribute__Clang正告解决预处理插入编译期脚本进步我的项目编译速度对于不想看我啰里八嗦讲一大堆原理的同学,能够间接跳到本文的最初一个章节。 一、iOS编译Objective C采纳Clang(swift采纳swiftc)作为编译器前端,LLVM作为编译器后端。 简略的编译过程如图 (一)编译器前端编译器前端的工作是进行:词法剖析,语法分析,语义剖析,生成中间代码(intermediate representation )。在这个过程中,会进行类型查看,如果发现错误或者正告会标注进去在哪一行。 (二)编译器后端编译器后端会进行机器无关的代码优化,生成机器语言,并且进行机器相干的代码优化。iOS的编译过程,后端的解决如下LVVM优化器会进行BitCode的生成,链接期优化等等。 LLVM机器码生成器会针对不同的架构,比方arm64等生成不同的机器码。 二、执行一次XCode build的流程当你在XCode中,抉择build的时候(快捷键command+B),会执行如下过程 编译信息写入辅助文件,创立编译后的文件架构(name.app)解决文件打包信息,例如在debug环境下 Entitlements:{ "application-identifier" = "app的bundleid"; "aps-environment" = development;}执行CocoaPod编译前脚本 例如对于应用CocoaPod的工程会执行CheckPods Manifest.lock编译各个.m文件,应用CompileC和clang命令。 CompileC ClassName.o ClassName.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compilerexport LANG=en_US.US-ASCIIexport PATH="..."clang -x objective-c -arch x86_64 -fmessage-length=0 -fobjc-arc... -Wno-missing-field-initializers ... -DDEBUG=1 ... -isysroot iPhoneSimulator10.1.sdk -fasm-blocks ... -I 上文提到的文件 -F 所须要的Framework -iquote 所须要的Framework ... -c ClassName.c -o ClassName.o通过这个编译的命令,咱们能够看到 ...

March 9, 2022 · 5 min · jiezi

关于objective-c:Proxy消息转发实战

情谊提醒:点击查看本文所波及的demo代码 导语代理即是代表受权方处理事务(From Wikipedia)。 思考一下咱们生存中什么时候会用到代理呢? 租房、买房时,咱们须要一位中介帮咱们分割房东,解决手续上的事件,升高咱们和房东的沟通老本。叫外卖时,咱们须要外卖小哥帮咱们送外卖,好让咱们有更多工夫去专一别的事件。所以能够了解为中介帮咱们解决两个层面上的问题: 缩小相互依赖的问题缩小做反复的事件所以从实质上来说,Proxy体现的还是"中间层"的设计思维,具体利用于"音讯转发"的业务场景。 循环援用在讲述明天这个Demo前,咱们先回忆一下之前咱们接触过的Proxy的利用场景,我想你脑海中必定第一工夫浮现出:应用Proxy解决NSTimer循环援用的问题。 所以咱们首先聊一聊 Proxy 应用最刚需的 「解决循环援用」的场景。 循环援用是怎么产生的下图是内存失常回收的过程: 上面是产生循环援用导致内存透露的过程: 验证是否产生循环援用的最佳形式就是判断是否产生了一个援用环。 NSTimer 循环援用问题NSTimer 问题最乏味的点是,网上对于 NSTImer 为什么会导致循环援用的解释 80%都是不清晰的,比方这样一个最广泛的说法: 这样的说法就好似有人问小明:"NSTimer为什么会导致循环援用?" 小明却答复:"NSTimer会导致循环援用"。 演出了一出"搁着搁着呢"的好戏。 循环援用肯定是 ViewController 和 NSTimer 互相强援用,但为什么 NSTimer addTarget 会导致循环援用,但平时咱们应用的 UIButton addTarget却不会导致循环援用呢? 答复分明这个问题,才算是说分明了"NSTimer为什么会导致循环援用"。 其实解答这个问题也很简略 咱们查一下大苹果提供的文档阐明, 对于 UIControl : The control does not retain the object in the target parameter. It is your responsibility to maintain a strong reference to the target object while it is attached to a control. ...

March 9, 2022 · 2 min · jiezi

关于objective-c:如何优雅地压缩一张图片

平时开发中咱们常常会接到这样的需要:上传图片前,须要把图片压缩到100KB以下,且要尽可能的清晰。 作为一名有直觉的开发,咱们即刻三下五除二搞个压缩因子: NSData *imageData = UIImageJPEGRepresentation(image, 0.8);(为什么不必 UIImagePNGRepresentation 而应用 UIImageJPEGRepresentation 能够Google,这里不做解释了哈)后果发现用户可能会抉择10MB的图片,0.8的压缩因子只能压到3MB,这必定不能够的哇。 那咱们来个循环压!直到压到指标为止! NSData *imageData = UIImageJPEGRepresentation(image, imageCompressRate);; while (imageData.length > 100 * 1024) { imageCompressRate -= 0.1; imageData = UIImageJPEGRepresentation(image, imageCompressRate); }你写完下面这个代码,测试了几张图片,称心如意地提交了代码,但过了几天发现有人在上传图片的时候卡死了!这是肿么肥四! 一查原来是刚写的 while循环压 死循环了!What?! 拿了用户反馈的图片进行复现,后果发现如果是很大的图,压缩因子即便再怎么小,也压不动了。 上面以11MB的图片为例,看看压缩后果和压缩因子的关系: 从这个压的后果咱们能够失去两个论断: 只靠压是不能把一张图片有限压为靠近0大小的压缩因子在1~0.8期间变更影响显著,0.8之后压完差别不大好家伙,居然怎么压都压不为0,那咱们的 while循环压 绝壁会呈现死循环的可能呀,那怎么办呢? 解决方案最初必定会说的啦,在介绍解决方案前,咱们先思考一下, UIImageJPEGRepresentation 为什么会呈现"压不动"的状况? 图片的大小是用 : 宽 x 高 x 位深 来计算的,UIImageJPEGRepresentation 的压缩形式理论是将 几个像素点用一个像素点来示意,也就是在 位深 上做文章,不会影响图片的 bitmap(宽 x 高), 所以如果图片比拟大,那么听凭用 UIImageJPEGRepresentation 怎么压,都会压到一个阈值,不会靠近于0的。 原理搞清楚了,咱们来思考下怎么 优雅地压缩一张图片吧!先间接上代码: /* 依据图片大小,获取图片压缩因子 */+ (CGFloat)getCompressRateByImageSize:(CGFloat)imageSize targetSize:(CGFloat)targetSize { NSUInteger rate = (NSUInteger)(imageSize / targetSize); rate = (rate == 0) ? 1 : rate; // 默认0.8压缩因子 CGFloat maxCompressRate = 0.8; CGFloat minCompressRate = 0.2; // 反比例压缩函数 CGFloat compressRate = 0.8 / rate; compressRate = MIN(MAX(compressRate, minCompressRate), maxCompressRate); return compressRate;}/*! * @brief 使图片压缩后刚好小于指定大小 * * @param image 以后要压缩的图 maxLength 压缩后的大小 * * @return 图片对象 */+ (NSData *)compressImageSize:(UIImage *)image toByte:(NSUInteger)maxLength { // 压 NSData *data = UIImageJPEGRepresentation(image, 1); if (data.length < maxLength) { return data; } CGFloat compressRate = [self.class getCompressRateByImageSize:data.length targetSize:maxLength]; data = UIImageJPEGRepresentation(image, compressRate); if (data.length < maxLength) { return data; } // 缩 UIImage *resultImage = [UIImage imageWithData:data]; NSUInteger lastDataLength = 0; while (data.length > maxLength && data.length != lastDataLength) { lastDataLength = data.length; CGFloat ratio = (CGFloat)maxLength / data.length; CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), (NSUInteger)(resultImage.size.height * sqrtf(ratio))); if (CGSizeEqualToSize(size, CGSizeZero) || size.width < 10 || size.height < 10) { break; } UIGraphicsBeginImageContext(size); [resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); data = UIImageJPEGRepresentation(resultImage, compressRate); } return data;}逻辑也不简单,既然 单纯压 会呈现 压不动的状况,那咱们就先压后缩,鉴于 UIImageJPEGRepresentation 压缩存在疾速损失的状况(达到阈值后,压1次和2次的成果都是一样的), ...

March 9, 2022 · 2 min · jiezi

关于objective-c:ObjectiveC-之-block

前言作为iOS开发,咱们素日里会高频应用block,block十分重要,在学习Swift闭包时,我忽然感觉能够将 Objective-C block 和 Swift闭包 一起比照学习。 如果你针对上面的问题曾经有了比拟深的了解,那么能够略过本篇文章: block 的数据结构block 的内存机制block 和 weakify/strongify 的关联Swift闭包和 Objective-C block的区别dispatch_block_t 的利用场景一、block的数据结构(一)block 语法解析作为硬核派,理解block数据结构咱们必定不能Google他人的论断,咱们有本人的clang工具,应用clang工具,能够将 OC 代码转成 C++ 代码。 首先,咱们筹备 main.m 这个类,类内容为: // main.m int main() { return 1;}咱们切到main.m类所在文件夹,应用指令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m,发现语法解析生成的cpp代码如下main.cpp: // main.cpp#import <UIKit/UIKit.h>int main() { void (^block)(void) = ^ { NSLog(@"Hello World!"); }; block(); return 1;}接着咱们在main.m中增加block代码: // main.m int main() { void (^block)(void) = ^ { }; block(); return 1;}持续应用clang解析main.m,发现生成的cpp代码如下: // main.cppstruct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0* Desc; __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) { impl.isa = &_NSConcreteStackBlock; impl.Flags = flags; impl.FuncPtr = fp; Desc = desc; }};static void __main_block_func_0(struct __main_block_impl_0 *__cself) { NSLog((NSString *)&__NSConstantStringImpl__var_folders_9b_w0ymsg0n3yqdlb90w49xqmz40000gn_T_main_2428cf_mi_0); }static struct __main_block_desc_0 { size_t reserved; size_t Block_size;} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};int main() { void (*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA)); ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block); return 1;}static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };去除强制转换后咱们能够看出申明block的时候,block底层调用了__main_block_iml_0构造体,传入的参数别离是__main_block_func_0(办法函数)和&__main_block_desc_0_DATA(构造体地址)。 ...

March 6, 2022 · 4 min · jiezi

关于objective-c:Nodejs-学习笔记

Nodejs 学习笔记**这个公众号会继续更新技术计划、关注业内技术动向,关注一下老本不高,错过干货损失不小。↓↓↓** 一、Nodejs介绍(一)根本介绍 Node.js 是一个 JavaScript 运行环境(runtime),它让 JavaScript 能够开发后端程序,简直能实现其它后端语言的所有性能。 Nodejs最善于的是解决高并发:在 Java、PHP 或者 .net 等服务器端语言中,会为每一个客户端连贯创立一个新的线程。而每个线程须要消耗大概 2MB 内存。也就是说,实践上一个 8GB 内存的服务器能够同时连贯的最大用户数为 4000 个左右。 要让 Web 应用程序反对更多的用户,就须要减少服务器的数量,而 Web 应用程序的硬件老本就回升了。 Node.js 不为每个客户连贯创立一个新的线程,而仅仅应用一个线程。当有用户连贯,就触发一个外部事件,通过非阻塞 I/O 、事件驱动机制,让 Node.js 程序宏观上也是并行的。 应用 Node.js,一个 8GB内存 的服务器,能够同时解决超过4万用户的连贯。 (二)开发工具 举荐应用 VSCode 装置好 Node Snippets 插件 二、HTTP模块、URL模块、supervisor工具(一)HTTP模块如果应用 PHP 来编写后端diamante,须要 Apache 或者 Nginx 的 HTTP 服务器,来解决客户端的申请响应。不过对 Node.js 来说,概念齐全不一样。应用 Node.js 时,咱们不仅仅在实现一个利用,同时还实现了整个 HTTP 服务器。 Tips : ctrl + c 终止服务器 // 示意引入 http 模块var http = require('http');/* request : 获取 url 传过来的信息 response : 给浏览器响应信息*/http.createServer(function (request, response) { // 设置响应头 response.writeHead(200, {'Content-Type': 'text/plain'}); // 示意给咱们的页面下面输入的一句话并且完结响应 response.end('Hello World');}).listen(8081); // 端口console.log('Server running at http://127.0.0.1:8081/');(二)URL模块url 模块也是 nodejs 内置模块。 ...

March 6, 2022 · 6 min · jiezi

关于objective-c:iOS开发面试只需知道这些技术基本通关性能优化篇

在性能优化中一个最具参考价值的属性是FPS:FramesPerSecond,其实就是屏幕刷新率,苹果的iphone举荐的刷新率是60Hz,也就是说GPU每秒钟刷新屏幕60次,这每刷新一次就是一帧frame,FPS也就是每秒钟刷新多少帧画面。静止不变的页面FPS值是0,这个值是没有参考意义的,只有当页面在执行动画或者滑动的时候,FPS值才具备参考价值,FPS值的大小体现了页面的晦涩水平高下,当低于45的时候卡顿会比拟显著。 图层混合: 每一个 layer是一个纹理,所有的纹理都以某种形式重叠在彼此的顶部。对于屏幕上的每一个像素,GPU须要算出怎么混合这些纹理来失去像素 RGB的值。 当 Sa = 0.5时,RGB值为(0.5,  0, 0),能够看出,当两个不是齐全不通明的 CALayer笼罩在一起时,GPU大量做这种复合操作,随着这中操作的越多,GPU越繁忙,性能必定会受到影响。 公式: R = S + D * ( 1 – Sa ) 后果的色彩是源色调(顶端纹理)+指标色彩(低一层的纹理)*(1-源色彩的透明度)。当 Sa = 1时,R = S,GPU将不会做任何合成,而是简略从这个层拷贝,不须要思考它下方的任何货色(因为都被它遮挡住了),这节俭了 GPU相当大的工作量。 一、入门级1、用 ARC治理内存 2、在正确的中央应用  reuseIdentifier 3、尽量把 views设置为通明 4、防止过于宏大的  XIB 5、不要阻塞主线程 6、在 ImageViews中调整图片大小。如果要在 UIImageView中显示一个来自  bundle的图片,你应保障图片的大小和 UIImageView的大小雷同。在运行中缩放图片是很消耗资源的,特地是 UIImageView嵌套在UIScrollView中的状况下。如果图片是从远端服务加载的你不能管制图片大小,比方在下载前调整到适合大小的话,你能够在下载实现后,最好是用  backgroundthread,缩放一次,而后在 UIImageView中应用缩放后的图片。 7、抉择正确的 Collection。 Arrays:有序的一组值。应用  index来  lookup很快,应用  value lookup很慢,插入/删除很慢。Dictionaries:存储键值对。用键来查找比拟快。Sets:无序的一组值。用值来查找很快,插入/删除很快。8、关上 gzip压缩。app可能大量依赖于服务器资源,问题是咱们的指标是挪动设施,因而你就不能指望网络情况有多好。减小文档的一个形式就是在服务端和你的 app中关上 gzip。这对于文字这种能有更高压缩率的数据来说会有更显著的效用。iOS曾经在  NSURLConnection中默认反对了 gzip压缩,当然  AFNetworking这些基于它的框架亦然。 二、中级1、重用和提早加载(lazy load) Views 更多的  view意味着更多的渲染,也就是更多的 CPU和内存耗费,对于那种嵌套了很多view在UIScrollView里边的  app更是如此。这里咱们用到的技巧就是模拟 UITableView和 UICollectionView的操作:不要一次创立所有的 subview,而是当须要时才创立,当它们实现了使命,把他们放进一个可重用的队列中。这样的话你就只须要在滚动产生时创立你的 views,防止了不划算的内存调配。2、Cache, Cache,还是   Cache! ...

August 25, 2021 · 3 min · jiezi

关于objective-c:八天让iOS开发者上手Flutter七

上一篇文章咱们曾经实现首页聊天页面的导航条和列表展现,明天的工作是实现搜寻cell的展现和点击之后的搜寻页面的性能。 自定义SearchCell新建search_cell.dart文件 实现SearchCell代码SearchCell的话,因为仅仅只是展现,点击之后就进入搜寻页了,应该来说是不须要状态的,所以用一个StatelessWidget就够了。而后布局的形式应用一个Container蕴含一个Row,Row里面包一个图片和文本就能够了。布局的形式其实多种多样,能实现就好了。残缺代码如下: 一个有意思的中央是,flutter外面的Image竟然能够设置色彩,而且色彩是设置给图片的。比方我的放大镜图片本来是彩色的,设置红色之后,竟然真的变红色了!!! 应用SearchCellSearchCell的展现就算写完了,而后在ChatPage.dart中应用,咱们把ListView的itemBuilder办法抽取进去,而后因为咱们多加了一个SearchCell,所以itemCount须要加1,而后取_chatList数据的时候也要解决一下下标。 自定义SearchPage新建search_page.dart文件 简略实现SearchPageSearchPage作为一个页面,应用StatelessWidget必定是无奈胜任的,所以应用一个StatefulWidget。而因为AppBar的款式和咱们须要显示的效果图还是有差异的,所以这里咱们不应用Scaffold提供的AppBar了。咱们自定义一个SearchBar,配合一个ListView来搭建根本的布局。这外面根本没有陈腐的货色,就简略贴一下代码: SearchBar因为是在SearchPage中应用的,所以就间接定义在SearchPage中了,代码也是先简略定义如下: 点击跳转到SearchPage 在搜寻cell外面实现点击办法,而后跳转到SearchPage,显示成果如图: 实现SearchBarSearchBar的布局SearchBar的布局,最外层分为高低两个局部,下面的局部是零碎状态栏的高度。上面的局部就是显示搜寻条的高度。而搜寻条的布局,应用Row分隔为左右两个局部,左侧蕴含放大镜,文本输入框和删除图片。右侧就是一个返回下级页面的勾销。这里次要提一下flutter中的文本框,跟iOS中UITextField真的很不一样,UITextField中左侧的图标,右侧的删除,都是封装在外部的。而在flutter中,文本框TextField真的就只有文本框,没有其余的货色,都须要本人增加。残缺代码如下: SearchBar事件处理勾销的解决点击勾销须要pop到上一个界面,给勾销加一个GestureDetector实现onTap就好了。代码如下: 革除按钮性能实现首先作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这是一个我的iOS开发公众号:编程大鑫,不论你是小白还是大牛都欢送入驻 ,让咱们一起提高,独特倒退!(群内会收费提供一些群主珍藏的收费学习书籍材料以及整顿好的几百道面试题和答案文档!)未输出文本的时候,不显示革除按钮。有输出文本的时候,显示革除按钮。点击革除按钮,清空文本内容并暗藏革除按钮。 应用一个bool值_showClear管制革除按钮的显示暗藏。代码如下: 在文本变动的时候,批改_showClear值并刷新状态。文本的变动在TextField的onChanged属性就能够监听到。代码如下: 最初就是革除按钮的点击性能,因为须要清空TextField的文本内容,须要应用到TextEditingController,给TextField的controller属性赋值,而后通过TextEditingController对象革除文本内容。文本革除之后并不会主动调用零碎的onChanged办法,本人手动调用一下就好了。代码如下: SearchBar回调文本框的内容文本框的内容变动的时候,须要回调给SearchBar内部,这样咱们能力在SearchPage页面进行搜寻内容。应用一个回调作为参数就能够实现了。代码如下: onChanged是一个闭包属性,在初始化SearchBar的时候传入,在TextField的文本变动的时候调用闭包,并将文本作为参数回传给SearchBar内部。因为将onChanged作为了必传参数,所以编译器天然会在用到了SearchBar的中央报错。很容易找到报错的中央,加个参数就好了。 SearchBar相干的代码就算差不多实现了,其实能够将SearchBar独自作为一个文件独立进去。接下来就是解决SearchPage了 实现SearchPage搜寻页面的搜寻性能,往细了说,能够搜寻很多内容,咱们这里只是简略的搜寻名字,只有名字蕴含输出的内容,就将搜寻后果展现进去。因为这里对中文名进行搜寻的时候,能匹配到的数据比拟少,所以这里曾经将网络申请返回的名字由中文改为英文名字了。后面展现中文名字的截图就不做批改了。 SearchPage的搜寻性能增加datas数据源要实现SearchPage的搜寻性能,那么它首先必须要有数据源,很显著它的数据源是从首页来的。先定义一个datas,作为必传参数,而后通过内部层层传递过去。 datas定义好了当前,报红色谬误的中央,就是须要传参数的中央,很不便,都不必咱们本人去翻哪里须要加参数了。发现SearchCell外面须要传入数据源,同样的形式,在SearchCell外面定义datas,而后在报错的中央解决。 就这样子顺藤摸瓜,直到来到chat_page将数据源传入就实现了 SearchPage本人的数据源SearchPage须要展现搜寻之后的后果,所以本人定义一个数组用来寄存搜寻的后果。并且临时先应用Text做一个最简略的展现。代码如下: 实现搜寻性能并展现数据搜寻的性能实现很简略,就是判断数据源外面的名字是否蕴含输出的文本,如果蕴含就全副增加并展现。 代码如下: APP上如图,我输出son,显示后果: SearchPage的搜寻后果列表展现SearchPage的搜寻后果列表展现的数据款式,应该和首页是相似的。所以能够间接应用首页的布局。代码如下: SearchPage高亮显示搜到的后果这里的思路是,高亮显示搜到的后果,那么一般的文本必定是不行了,必须是富文本。如何找到搜寻的关键字在文本中的地位呢,这个不必咱们思考了。flutter中对字符串有一个分隔办法split,这个办法跟iOS中的字符串的componentsSeparatedByString:办法相似,依据传入的参数来分隔字符串。这里贴一下iOS的代码: (还是Xcode看着悦目啊)咱们将字符串abcaa以字符a分组,再将分组的后果拼接回原来的字符串。为什么要这么操作?因为从新拼接新字符串的时候,咱们就能够解决富文本字符串了。当初回到flutter中来,flutter中拼接的富文本的形式太不便了,RichText花色拼接TextSpan这个咱们在后面也讲过了。 _searchKey就是咱们输出的文本,在SearchPage中申明属性,在SearchBar的回调中赋值就好了。 当初测试一下,输出son,APP显示如图: 滚动列表叫回键盘ListView的滚动,咱们在后面曾经说过一次,须要将ListView包在NotificationListener外面。而后叫回键盘的代码FocusScope.of(context).requestFocus(FocusNode());这个记住就好了,代码如下: 总结到这里咱们的flutter仿微信Demo性能就差不多完了,还剩最初一篇就是介绍flutter和原生混合开发的一些货色。这个也是理论我的项目中应该常常会遇到的状况。其实写到这里会发现很多货色和原生都是相通的或者相似的。除了新的语言Dart不是很相熟之外,其余很多中央比方很多属性的名字,色彩,闭包,都可能看到原生的影子。flutter创造者们也不会闭门造车,都会去借鉴原生外面的货色。

August 24, 2021 · 1 min · jiezi

关于objective-c:八天让iOS开发者上手Flutter六

筹备网络数据这一步不是很重要,提供一些假数据而已,不是重点嫌麻烦的能够跳过。 先介绍一个网址:点击 这个网址用来搭建咱们须要的网络数据,注册账号非常简单,这里就不多说了。 注册实现之后,新建一个仓库,简简单单取个名字就够了: 之后点击进入仓库,能够看到下图: 会默认生成以一个示例接口,能够看一看示例接口的生成规定。看不懂也没关系,咱们间接间接上手本人新建一个接口,如图所示: 点击右上角的编辑按钮进入编辑模式,新建一个响应chatlist,类型为Array。而后生成chatlist的数据,imageUrl示意每条聊天数据的用户头像。其中用户头像的初始值外面有一段@natural(20,99),这个是Mock.js代码。这里是相干介绍mockjs.com/ 每条聊天数据,除了imageUrl还须要有用户名name和音讯的内容message。@cname用来生成随机的中文名,@cparagraph用来生成随机的中文段落来示意聊天内容。咱们这里只是简略的结构一下这个聊天列表所须要的数据,真正的聊天列表的数据必定是不会这么简略的。。。 编辑的差不多的时候,记得点击保留,保留之后点击红圈中的图标就能够获取到数据 聊天页面导航条筹备工作默认展现页面改为_currentIndex改为0,新建chat目录,将相干文件放在这里。 增加加号按钮加号按钮这个货色,咱们之前曾经增加过相似的了,appBar的actions就是咱们须要增加代码的中央。 如果咱们依照这个思路写下去的话,就须要本人再去实现一个弹出菜单的类。其实flutter提供了咱们一些现成的类能够做到相似的成果。 PopupMenuButtonPopupMenuButton类用来弹出一个菜单,必传参数为itemBuilder,用来实现它须要展现的内容。PopupMenuItem就是用来展现内容的类。这里有一个细节说一下,PopupMenuButton有一个onSelected属性,这个属性是个闭包,意思是选中某个PopupMenuItem的时候,会调用这个闭包。然而有一个前提就是每个PopupMenuItem的value必须不为null的时候,才会执行onSelected闭包,我在这里卡了半天,网上找了半天材料也没有明确讲到这里。其余就没什么好讲的了,都比较简单。 还有一个小细节,如何设置PopupMenuButton的色彩,能够间接设置它的色彩 还能够设置APP的主题的cardColor,不过这个优先级没有间接设置PopupMenuButton色彩高。 申请网络数据pub.flutter-io.cn/ 这个网站能够搜寻flutter应用的包packages。咱们应用http这个包来申请咱们的网络数据。这个包是flutter官网提供的。理论我的项目开发的时候可能并不会应用http这个包,大部分是应用dio来申请网络数据。这里只介绍官网的http包如何应用。 导入http包首先作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这是一个我的iOS开发公众号:编程大鑫,不论你是小白还是大牛都欢送入驻 ,让咱们一起提高,独特倒退!(群内会收费提供一些群主珍藏的收费学习书籍材料以及整顿好的几百道面试题和答案文档!) 粘贴实现之后须要更新一下,就是获取一下包对应的代码。能够通过上方的Pub get,也能够在终端中输出flutter packages get 命令执行完之后,就能够应用这个包了。 导入http头文件并取别名 发送申请 申请的发送写在initState外面。getData()前面跟了一个async示意的是异步执行。async须要搭配await应用,await前面跟着的是耗时的代码。所以下面的程序会先打印来了,而后再输入申请的状态码; 点击其余的页面,再次回到以后页面会发现initState办法从新走了一遍,这是因为咱们还没有保留住状态,前面会讲到如何放弃Widget的状态。 解决返回的数据首先介绍一下,在flutter中如何将申请返回的JSON数据转为Map,在咱们iOS开发中是转为字典,而flutter中没有字典这个类型,对应的类型是Map。以及如果将Map转为JSON。在iOS中咱们晓得会应用一个NSJSONSerialization的类用来解决JSON数据。同样的,在flutter中也会有一个专门的类JsonCodec来解决。 JSON和Map相互转 其中的json就是JsonCodec的实例。须要导入'dart:convert'头文件。flutter中还能够通过is来判断是不是某个类型。 新建聊天模型 除了红框内的办法之外,其余没什么陈腐事物。红框内的办法应该说是一个工厂办法,是设计模式的一种,用来初始化对象的。除了默认的初始化办法,还能够应用这个工厂办法来实例化一个Chat对象。模型建设好了之后就能够解决响应的数据了 解决响应的数据 这里用到了Future,对于Future的解说能够看官网文档dart.cn/tutorials/l… 应用FutureBuilder显示界面很多时候咱们会依赖一些异步数据来动静更新UI,比方在关上一个页面时咱们须要先从互联网上获取数据,在获取数据的过程中咱们显示一个加载框,等获取到数据时咱们再渲染页面;当然,通过StatefulWidget咱们齐全能够实现上述这些性能。但因为在理论开发中依赖异步数据更新UI的这种场景十分常见,因而Flutter专门提供了FutureBuilder来疾速实现这种性能。FutureBuilder会依赖一个future,它会依据所依赖的future的状态来动静构建本身。这个future咱们刚刚曾经筹备好了。对于FutureBuilder的介绍就不具体介绍了。 最初残缺代码如下: 不应用FutureBuilder的形式刚刚说了,咱们能够应用FutureBuilder来疾速实现展现异步网络数据,也能够本人实现,当初咱们本人实现一下。应用一个公有变量_chatList记录申请下来的数据,再依据_chatList的值来展现不同的页面。代码如下: 因为getData的返回值是Future的起因,getData()前面能够跟then办法,还能够跟谬误捕捉catchError,实现时的回调whenComplete,超时设置timeOut等等,这种写法挺有意思,一路点上来就完了... 实现超时勾销刷新性能 在每次申请的时候,重置_cancelConnect的值。 放弃Widget的状态咱们来回点击通讯录页面和聊天页面,会发现每次点击进入以后的页面,都会从新的载入,initState()会被从新调用。将通讯录页面滑动到底部,再次点击进入会发现又默认回到了顶部。为什么会呈现这样的问题。正是因为咱们的Widget的状态没有放弃,每次展现都从新创立了。 Dart语言中有一个Mixins的概念:官网的解释是这样,能够给类A Mixins 一个B,那么A就领有了B的属性和办法。有点像OC的类扩大的意思。放弃Widget的状态就须要用到这个语言个性。一共有三个步骤: 1. Mixins 类AutomaticKeepAliveClientMixin 重写wantKeepAlive办法调用父类Builder办法 同样把通讯录页面也实现下面的步骤。而后再次来回点击发现还是没有放弃住状态???这里有一个最大的问题就是咱们的根Widget都没有放弃住状态,那还谈什么放弃子Widget的状态呢。。。 应用PageView来到rootPage.dart文件,咱们会看到body外面间接取了数组的某个元素作为根Widget展现。这样是无奈放弃住状态的,应用PageView才能够放弃住状态。 ...

August 19, 2021 · 1 min · jiezi

关于objective-c:iOS开发面试只需知道这些技术基本通关数据结构与算法篇附加安全加密

一、数据结构汇合构造 线性构造 树形构造 图形构造 1.1、汇合构造 说白了就是一个汇合,就是一个圆圈中有很多个元素,元素与元素之间没有任何关系 这个很简略 1.2、线性构造 说白了就是一个条线上站着很多集体。 这条线不肯定是直的。也能够是弯的。也能够是值的 相当于一条线被分成了好几段的样子 (施展你的想象力)。 线性构造是一对一的关系 1.3、树形构造 说白了 做开发的必定或多或少的晓得 xml 解析 树形构造跟他十分相似。也能够设想成一个金字塔。树形构造是一对多的关系 1.4、图形构造 这个就比较复杂了。他呢 无穷。无际 无向(没有方向)图形机构 你能够了解为多对多 相似于咱们人的交加关系 数据结构的存储 数据结构的存储个别罕用的有两种 顺序存储构造 和 链式存储构造 2.1 顺序存储构造 施展想象力啊。 举个列子。数组。1-2-3-4-5-6-7-8-9-10。这个就是一个顺序存储构造 ,存储是按程序的 举例说明啊。 栈,做开发的都相熟。栈是先进后出 ,后进先出的模式 对不对 ? 他的你能够这样了解,hello world 在栈外面从栈底到栈顶的逻辑顺次为 h-e-l-l-o-w-o-r-l-d 这就是顺序存储,再比方队列 ,队列是先进先出的对吧,从头到尾 h-e-l-l-o-w-o-r-l-d 就是这样排对的 2.2 链式存储构造 再次施展想象力 这个略微简单一点 这个图片我始终弄好 ,回头找美工问问,再贴上 例如 还是一个数组1-2-3-4-5-6-7-8-9-10 链式存储就不一样了 1(地址)-2(地址)-7(地址)-4(地址)-5(地址)-9(地址)-8(地址)-3(地址)-6(地址)-10(地址)。每个数字前面跟着一个地址 而且存储模式不再是程序 ,也就说程序乱了,1(地址)1 前面跟着的这个地址指向的是 2,2 前面的地址指向的是 3,3 前面的地址指向是谁你应该分明了吧。他执行的时候是 1(地址)-2(地址)-3(地址)-4(地址)-5(地址)-6(地址)-7(地址)-8(地址)-9(地址)-10(地址),然而存储的时候就是齐全随机的。明确了? 单向链表\双向链表\循环链表 还是举例子。了解最重要。不要去死记硬背 哪些什么。定义啊。逻辑啊。了解才是最重要滴 3.1 单向链表 A->B->C->D->E->F->G->H. 这就是单向链表 H 是头 A 是尾 像一个只有一个头的火车一样 只能一个头拉着跑 3.2 双向链表 数组和链表区别: ...

August 17, 2021 · 2 min · jiezi

关于objective-c:北京一卡通APP-iOS研发手册v101

前言一、我的项目架构 我的项目依照代码的组织构造和调用关系,能够分为四层,别离是视图层、业务层、根底模块和数据拜访层。其中视图层负责页面展现和与用户交互(如用户的点击事件、划动手势等),业务层则对应具体的业务,例如充值模块、用户信息、乘车码、多扣票款等,根底模块蕴含了我的项目运行各个性能最根本的能力和组件,比方网络模块负责业务的网络申请,平安模块负责报文的加解密和签名验签,存储模块负责本地的数据长久化等等,数据拜访层是对我的项目所用到的所有信息的获取形式的形象和封装,包含从接口获取数据,从本地资源文件、本地缓存以及数据库等获取数据。 上面别离对各个模块做下介绍: 1、视图层2、业务层3、根底模块4、数据拜访层二、我的项目目录构造1、工程目录构造工程目录构造如下: 我的项目采纳了cocoapods的集成形式,目录构造次要分为Base、Common、Macro、Main、Resources、Sources、Supporting Files、Vendors、Pods。 其中, Base目录下是我的项目用到的根底ViewController的封装,蕴含加载WebView的,加载原生页面的,曾经他们的独特基类。Common目录蕴含了我的项目用到的公共代码。Macro是对我的项目罕用的宏的汇总。Main是我的项目的主代码目录。Resources是我的项目的资源文件,蕴含图片、预置离线包等。Sources是程序启动相干的源文件。Supporting Files蕴含了main.m也就是程序的入口文件,还有info.plist程序的配置文件,还有启动图等等。Vendors是手动导入的第三方库。Pods目录下是通过pod导入的第三方库。2、mPaas目录构造mPaaS目录构造如下: └── MPaaS ├── mpaas_sdk.config ├── Targets | └── mPaaSDemo(工程 Target 名称) | ├── mPaaSDemo-mPaaS-Headers.h | ├── mPaaSDemo-Prefix.pch | ├── APMobileFramework | ├── mPaas | ├── meta.config | └── yw_1222.jpg ├── Resources └── Frameworks其中, mpaas_sdk.config:以后工程增加的模块信息,包含版本、增加工夫、资源文件等,由 mPaaS 插件主动保护,不得手动批改。mPaaSDemo-mPaaS-Headers.h:以后工程依赖的 mPaaS 模块的头文件,由 mPaaS 插件主动保护,不得手动批改。mPaaSDemo-Prefix.pch:以后工程 pch 文件的援用,会主动将 mPaaSdemo-mPaaS-Headers.h 退出 mPaaS 模块的头文件。APMobileFramework:mpaas 框架的生命周期治理的 category 文件。mPaas:MPaaSInterface 的 category 文件。meta.config:从 mPaaS 控制台下载的云端元数据。yw_1222.jpg:通过元数据中的 base64code 字段生成的无线保镖验签图片,在挪动网关验签时应用。如不须要挪动网关性能,可删除此图片。Resources & Frameworks:mPaaS 模块的资源文件和二进制文件目录,是以后工程所有 Targets 应用的 mPaaS 模块的并集,由 mPaaS 插件主动保护,不得手动批改。三、开发流程标准1、需要评审 产品在明确需要之后,通过邮件收回需要文档,而后招集大家一起进行需要评审。参加需要评审的人个别蕴含负责该项目标产品经理,已及相干测试人员,负责开发的前后端开发人员,局部重要我的项目领导也会参加评审。 ...

August 17, 2021 · 3 min · jiezi

关于objective-c:iOS开发面试只需知道这些技术基本通关多线程篇

一、过程、线程过程: · 1.过程是一个具备肯定独立性能的程序对于某次数据汇合的一次运行流动,它是操作系统分配资源的根本单元. · 2.过程是指在零碎中正在运行的一个应用程序,就是一段程序的执行过程,咱们能够了解为手机上的一个 app. · 3.每个过程之间是独立的,每个过程均运行在其专用且受爱护的内存空间内,领有独立运行所需的全副资源 线程 · 1.程序执行流的最小单元,线程是过程中的一个实体. · 2.一个过程要想执行工作,必须至多有一条线程.应用程序启动的时候,零碎会默认开启一条线程,也就是主线程 过程和线程的关系 · 1.线程是过程的执行单元,过程的所有工作都在线程中执行 · 2.线程是CPU 分配资源和调度的最小单位 · 3.一个程序能够对应多个过程(多过程),一个过程中可有多个线程,但至多要有一条线程 · 4.同一个过程内的线程共享过程资源 二、多过程、多线程多过程 关上 mac 的流动监视器,能够看到很多个过程同时运行 · 过程是程序在计算机上的一次执行流动。当你运行一个程序,你就启动了一个过程。显然,程序是死的(动态的),过程是活的(动静的)。 · 过程能够分为零碎过程和用户过程。但凡用于实现操作系统的各种性能的过程就是零碎过程,它们就是处于运行状态下的操作系统自身;所有由用户启动的过程都是用户过程。过程是操作系统进行资源分配的单位。 · 过程又被细化为线程,也就是一个过程下有多个能独立运行的更小的单位。在同一个工夫里,同一个计算机系统中如果容许两个或两个以上的过程处于运行状态,这便是多过程。 多线程 1. 同一时间,CPU 只能解决 1 条线程,只有 1 条线程在执行。多线程并发执行,其实是 CPU 疾速地在多条线程之间调度(切换)。如果 CPU 调度线程的工夫足够快,就造成了多线程并发执行的假象 2. 如果线程十分十分多,CPU 会在 N 多线程之间调度,耗费大量的 CPU 资源,每条线程被调度执行的频次会升高(线程的执行效率升高) 3. 多线程的长处: 能适当进步程序的执行效率能适当进步资源利用率(CPU、内存利用率)  多线程的毛病:开启线程须要占用肯定的内存空间(默认状况下,主线程占用 1M,子线程占用 512KB),如果开启大量的线程,会占用大量的内存空间,升高程序的性能线程越多,CPU 在调度线程上的开销就越大 程序设计更加简单:比方线程之间的通信、多线程的数据共享 三、工作、队列首先作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这是一个我的iOS开发公众号:编程大鑫,不论你是小白还是大牛都欢送入驻 ,让咱们一起提高,独特倒退!(群内会收费提供一些群主珍藏的收费学习书籍材料以及整顿好的几百道面试题和答案文档!)工作 就是执行操作的意思,也就是在线程中执行的那段代码。在 GCD 中是放在 block 中的。执行工作有两种形式:同步执行(sync)和异步执行(async) 同步(Sync):同步增加工作到指定的队列中,在增加的工作执行完结之前,会始终期待,直到队列外面的工作实现之后再继续执行,即会阻塞线程。只能在以后线程中执行工作(是以后线程,不肯定是主线程),不具备开启新线程的能力。 异步(Async):线程会立刻返回,无需期待就会继续执行上面的工作,不阻塞以后线程。能够在新的线程中执行工作,具备开启新线程的能力(并不一定开启新线程)。如果不是增加到主队列上,异步会在子线程中执行工作 队列 队列(Dispatch Queue):这里的队列指执行工作的期待队列,即用来寄存工作的队列。队列是一种非凡的线性表,采纳 FIFO(先进先出)的准则,即新工作总是被插入到队列的开端,而读取工作的时候总是从队列的头部开始读取。每读取一个工作,则从队列中开释一个工作在 GCD 中有两种队列:串行队列和并发队列。两者都合乎 FIFO(先进先出)的准则。两者的次要区别是:执行程序不同,以及开启线程数不同。 l 串行队列(Serial Dispatch Queue): 同一时间内,队列中只能执行一个工作,只有以后的工作执行实现之后,能力执行下一个工作。(只开启一个线程,一个工作执行结束后,再执行下一个工作)。主队列是主线程上的一个串行队列,是零碎主动为咱们创立的 l 并发队列(Concurrent Dispatch Queue): ...

August 12, 2021 · 3 min · jiezi

关于objective-c:iOS开发面试只需知道这些技术基本通关Runtime篇

一、objc对象的isa的指针指向什么?有什么作用?指向他的类对象,从而能够找到对象上的办法 详解:下图很好的形容了对象,类,元类之间的关系: 图中实线是 super_class 指针,虚线是 isa 指针。 1. Root class (class)其实就是 NSObject,NSObject 是没有超类的,所以 Root class(class)的 superclass指向 nil。 2. 每个 Class 都有一个 isa 指针指向惟一的 Meta class 3. Root class(meta)的 superclass 指向 Root class(class),也就是 NSObject,造成一个回路。 4. 每个 Meta class 的 isa 指针都指向 Root class (meta)。 二、一个NSObject对象占用多少内存空间?受限于内存调配的机制,一个 NSObject对象都会调配 16byte 的内存空间。 然而实际上在 64 位 下,只应用了 8byte;在 32 位下,只应用了 4byte 一个 NSObject 实例对象成员变量所占的大小,实际上是 8 字节 实质是 获取 Obj-C指针所指向的内存的大小,实际上是 16 字节 对象在分配内存空间时,会进行内存对齐,所以在 iOS 中,分配内存空间都是 16 字节 的倍数。能够通过以下网址 :openSource.apple.com/tarballs来查看源代码。 三、说一下对class_rw_t的了解?rw 代表可读可写。 ObjC 类中的属性、办法还有遵循的协定等信息都保留在class_rw_t 中: 四、说一下对class_ro_t的了解?存储了以后类在编译期就曾经确定的属性、办法以及遵循的协定。 五、说一下对isa指针的了解说一下对 isa 指针的了解, 对象的isa 指针指向哪里?isa 指针有哪两种类型? isa等价于 is kind of · 实例对象 isa 指向类对象 · 类对象指 isa 向元类对象 · 元类对象的 isa 指向元类的基类 ...

August 6, 2021 · 3 min · jiezi

关于objective-c:iOS开发面试只需知道这些技术基本通关block篇

一、什么是Block?Block 是将函数及其执行上下文封装起来的对象。比方: 通过 clang -rewrite-objc WYTest.m 命令编译该.m文件,发现该 block 被编译成这个模式: 其中 WYTest 是文件名,blockTest 是办法名,这些能够疏忽。其中WYTest blockTest_block_impl_0 构造体为 --block_impl 构造体为 block外部有 isa指针,所以说其本质也是 OC 对象 block 外部则为: 所以说 Block 是将函数及其执行上下文封装起来的对象 既然 block 外部封装了函数,那么它同样也有参数和返回值。 二、Block变量截获1、局部变量截获 是值截获。 比方: 这里的输入是 6 而不是 2,起因就是对局部变量 num的截获是值截获。同样,在 block里如果批改变量 num,也是有效的,甚至编译器会报错。 打印为 1,2,3 部分对象变量也是一样,截获的是值,而不是指针,在内部将其置为 nil,对 block 没有影响,而该对象调用办法会影响 2、部分动态变量截获 是指针截获。 输入为 2,意味着 num = 1 这里的批改 num 值是无效的,即是指针截获。同样,在 block 里去批改变量 m,也是无效的。 首先作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这是本鑫一个iOS开发公众号:编程大鑫,不论你是小白还是大牛都欢送入驻 ,让咱们一起提高,独特倒退!(群内会收费提供一些群主珍藏的收费学习书籍材料以及整顿好的几百道面试题和答案文档!)3、全局变量,动态全局变量截获:不截获,间接取值。咱们同样用 clang 编译看下后果。 编译后 ( impl.isa= &_NSConcreteStackBlock;这里留神到这一句,即阐明该 block是栈 block) 能够看到局部变量被编译成值模式,而动态变量被编成指针模式,全局变量并未截获。而--block 润饰的变量也是以指针模式截获的,并且生成了一个新的构造体对象: 该对象有个属性:num5,即咱们用--block 润饰的变量。这里--forwarding是指向本身的(栈 block)。 个别状况下,如果咱们要对 block 截获的局部变量进行赋值操作需增加--block 修饰符,而对全局变量,动态变量是不须要增加--block 修饰符的。 ...

August 2, 2021 · 1 min · jiezi

关于objective-c:iOS底层面试题中篇

7月,iOS求职跳槽的绝对较少,能在这个时间段求职的,不是被迫,就是对本人的技术很自信;针对7月,特地总结了第二份iOS常见大厂面试题(中); iOS面试题分为 上、中、下三局部,不便大家观看; 请先本人答一答! 话不多说;间接上题本文收录:公众号【iOS进阶宝典《iOS底层面试题(中篇)》】 6: iOS中内省的几个办法?class办法和objc_getClass办法有什么区别?1: 什么是内省?在计算机科学中,内省是指计算机程序在运行时(Run time)查看对象(Object)类型的一种能力,通常也能够称作运行时类型查看。 不应该将内省和反射混同。绝对于内省,反射更进一步,是指计算机程序在运行时(Run time)能够拜访、检测和批改它自身状态或行为的一种能力。2:iOS中内省的几个办法?isMemberOfClass //对象是否是某个类型的对象isKindOfClass //对象是否是某个类型或某个类型子类的对象isSubclassOfClass //某个类对象是否是另一个类型的子类isAncestorOfObject //某个类对象是否是另一个类型的父类respondsToSelector //是否能响应某个办法conformsToProtocol //是否遵循某个协定3:class办法分类办法和对象办法。实例class办法就间接返回object_getClass(self)类class办法间接返回self 4.object_getClass()获取的是类型,对象.isa --->类.isa --->元类.isa ---> 父元类.isa ---> 根元类.isa ---> 本人(还是根元类)7: 分类和扩大有什么区别?能够别离用来做什么?分类有哪些局限性?分类的构造体外面有哪些成员?1:分类次要用来为某个类增加办法,属性,协定(我个别用来为零碎的类扩大办法或者把某个简单的类的依照性能拆到不同的文件里)2:扩大次要用来为某个类原来没有的成员变量、属性、办法。注:办法只是申明(我个别用扩大来申明公有属性,或者把.h的只读属性重写成可读写的)分类和扩大的区别: 分类是在运行时把分类信息合并到类信息中,而扩大是在编译时,就把信息合并到类中的分类申明的属性,只会生成对应的成员变量,不会有getter/setter办法的申明和实现,而扩大会有。分类不可用为类增加实例变量,而扩大能够分类能够为类增加办法的实现,而扩大只能申明办法,而不能实现分类的局限性: 无奈为类增加实例变量,但可通过关联对象进行实现,注:关联对象中内存治理没有weak,用时须要留神野指针的问题,可通过其余方法来实现,具体可参考iOS weak 关键字漫谈分类的办法若和类中本来的实现重名,会笼罩本来办法的实现,注:并不是真正的笼罩 多个分类的办法重名,会调用最初编译的那个分类的实现 分类的构造体里有哪些成员 struct category_t { const char *name; //名字 classref_t cls; //类的援用 struct method_list_t *instanceMethods;//实例办法列表 struct method_list_t *classMethods;//类办法列表 struct protocol_list_t *protocols;//协定列表 struct property_list_t *instanceProperties;//实例属性列表 // 此属性不肯定真正的存在 struct property_list_t *_classProperties;//类属性列表};8:能不能简述一下 Dealloc 的实现机制Dealloc 的实现机制是内容治理局部的重点,把这个知识点弄明确,对于全方位的了解内存治理的只是很有 必要。 1.Dealloc 调用流程 1.首先调用 _objc_rootDealloc()2.接下来调用 rootDealloc()3.这时候会判断是否能够被开释,判断的根据次要有 5 个,判断是否有以上五种状况 ...

July 27, 2021 · 1 min · jiezi

关于objective-c:IOS开发的基础语言是什么

据说是一个什么面向对象的C的,那是什么语言啊,java根底的人能学吗? IOS开发的根底语言是objective-c,有Java根底学起来更加轻松。 IOS开发应用的语言是objective-c(也称object-c),是基于C++的。iOS开发的规范语言是objective-c。是c的一种超集, 它是对c的扩大,反对面向对象编程。像起初的一些高级语言java,c#等都借鉴了该语言的面向对象个性。 当然在iOS开发过程中,也反对c/c++语言与原生的objective-c混编。 扩大材料: Objective-C的长处和特点 根本特点Objective-C是十分实用的语言。它是一个用C写成很小的运行库,令应用程序的尺寸减少很小,和大部分OO零碎应用极大的VM执行工夫会取代了整个零碎的运作相同。Objective-C写成的程序通常不会比其原始码大很多。而其函式库(通常没附在软件发行本)亦和Smalltalk零碎要应用极大的内存来开启一个窗口的状况相同。因而,Objective-C它齐全兼容规范C语言(C++对C语言的兼容仅在于大部分语法上,而在ABI(Application Binary Interface)上,还须要应用extern "C"这种显式申明来与C函数进行兼容),而在此基础上减少了面向对象编程语言的个性以及Smalltalk音讯机制。 Objective-C的最后版本并不支[图片上传中...(vx二维码.jpg-a299f5-1625042289432-0)]持垃圾回收。在过后这是争执的焦点之一,很多人思考到Smalltalk回收时有漫长的死亡工夫,令整个零碎失去功能。Objective-C为防止此问题才不领有这个性能。尽管某些第三方版本已退出这个性能(尤是GNUstep), Apple在其Mac OS X 10.3中仍未引入这个性能。 另外,小编再通知大家,学习一门编程语言有点根底总是好的. 没有根底的话学习起来可能要艰难一些. 如果你有点java根底应该了解起来不是太艰难.但必竟两者不同,在编程个性和语言自身上还是有大差异的. 文章接下来还会继续更新,你也能够私信我及时获取最新材料以及面试相干材料。如果你有什么意见和倡议欢送给我留言。 #### 求喜爱IOS的小伙伴关注 !喜爱的话给一个赞吧!谢谢!谢谢!谢谢!

July 1, 2021 · 1 min · jiezi

关于objective-c:iOS处理多个网络请求的先后依赖关系

在iOS开发中咱们常常会遇到多网络申请的问题,有时候须要在一个网络申请完结之后再去申请另一个网络,其实最简略也是最low的办法就是在一个网络申请胜利的回调中再去申请另外一个接口信息应用信号量计数器来实现的代码如下: static NSString *userSign;static NSString *userId;dispatch_group_t group = dispatch_group_create();dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);dispatch_group_async(group, queue, ^{ [[BFLoginService shareInstance] getImSignWith: @"gjs598" complete:^(id _Nonnull data, RequestError * _Nonnull error) { // 工作1 NSLog(@"获取im签名实现%@", data[@"UserSig"]); userSign = data[@"UserSig"]; dispatch_semaphore_signal(semaphore); }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);});dispatch_group_async(group, queue, ^{ [[BFLoginService shareInstance] getImUserId:^(id _Nonnull data, RequestError * _Nonnull error) { // 工作2 NSLog(@"获取用户Id实现%@", data[@"userId"]); userId = data[@"userId"]; dispatch_semaphore_signal(semaphore); }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);});dispatch_group_notify(group, queue, ^{ NSLog(@"啊啊啊啊啊啊%@ ----- %@", userId, userSign); // 工作1/工作2都实现了, 当初执行工作3 [[V2TIMManager sharedInstance] login: userId userSig: userSign succ:^{ // NSLog(@"id登陆胜利"); // @weakify(self) [[V2TIMManager sharedInstance] getConversationList: INT_MAX count: INT_MAX succ: ^(NSArray<V2TIMConversation *> *list, uint64_t lastTS, BOOL isFinished) { // @strongify(self) // [self updateConversation: list]; NSLog(@"会话列表%@", list); } fail:^(int code, NSString *msg) { NSLog(@"拉取会话列表失败"); }]; } fail:^(int code, NSString *desc) { NSLog(@"id登陆失败了----------"); NSLog(@"%@", desc); }];});

May 17, 2021 · 1 min · jiezi

关于objective-c:objectivec入门

一. objective-c简介Objective-Objective-C是C语言的严格超集--任何C语言程序不经批改就能够间接通过Objective-C编译器,在Objective-C中应用C语言代码也是齐全非法的。Objective-C被形容为盖在C语言上的薄薄一层,因为Objective-C的原意就是在C语言主体上退出面向对象的个性。扩展名内容类型.h头文件。头文件蕴含类,类型,函数和常数的申明。蕴含头文件时,#import 选项和 #include 选项完全相同,只是它能够确保雷同的文件只会被蕴含一次。.m源代码文件。这是典型的源代码文件扩展名,能够蕴含 Objective-C 和 C 代码。.mm源代码文件。带有这种扩展名的源代码文件,除了能够蕴含Objective-C和C代码以外还能够蕴含C++代码。仅在你的Objective-C代码中的确须要应用C++类或者个性的时候才用这种扩展名。二. 语法1. 字符串大多数Objective-C通常不应用C语言格调的字符串。反之,大多数框架把字符串传递给NSString对象。NSString类提供了字符串的类包装,蕴含了所有你冀望的长处,包含对保留任意长度字符串的内建内存管理机制,反对Unicode,printf格调的格式化工具NSString* myString = @"My Stringn"; NSString* anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"];2. 类Objective-C 的类规格阐明蕴含了两个局部:定义(interface)与实现(implementation)。定义(interface)局部蕴含了类申明和实例变量的定义,以及类相干的办法。实现(implementation)局部蕴含了类办法的理论代码。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)。//Objective-C定义一个新的办法时,名称内的冒号(:)代表参数传递,不同于C语言以数学函数的括号来传递参数。Objective-C办法使得参数能够夹杂于名称两头,不用全副附缀于办法名称的尾端,能够进步程序可读性。设定色彩RGB值的办法为例: - (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 宣告办法*/ [myColor setColorToRed: 1.0 Green: 0.8 Blue: 0.2]; /* 呼叫办法*///这个办法的签名是setColorToRed:Green:Blue:。每个冒号前面都带着一个float类别的参数,别离代表红,绿,蓝三色。Implementation ...

April 8, 2021 · 1 min · jiezi

关于objective-c:iOS面试高薪进阶-你会这些呢嘛都是你需要的

这个栏目将继续更新--请iOS的小伙伴关注!做这个的初心是心愿能坚固本人的基础知识,当然也心愿能帮忙更多的开发者!根底>剖析>总结 面试iOS常见根底面试题(附参考答案)iOS底层原理之局部面试题剖析iOS 涨薪: Run Loop 面试题iOS面试反思总结iOS面试题文案及答案附件面试心得iOS 新东方面试面试iOS招聘题 机会在本人手中面试题 拓展:罕用框架和第三方框架Objective-CObjective-C与Swift的贯通编程Objective-C自定义UITextViewObjective-C语言的动态性Objective-C摸索Category底层的本质iOS 安防 优化优化iOS小技巧iOS 内存治理总结iOS开发---数据结构iOS平安攻防—常用工具iOS 多线程 线程间的状态iOS平安:Mach-O Type iOS 各种UI控件属性设置iOS平安根底之钥匙串与哈希iOS自动化布局-AutoLayout束缚优先级SwiftSwift开发之泛型实例Swift实现代码 iOS架构模式之MVPSwift WKWebView与JS的交互应用Swift进阶之路——单例模式、属性传值、代理传值、闭包传值Swift、OC别离实现用" | "隔开数组且只显示一行的小性能

November 6, 2020 · 1 min · jiezi

关于objective-c:ObjectiveC与Swift的混合编程

Swift 被设计用来无缝兼容 Cocoa 和 Objective-C 。在 Swift 中,你能够应用 Objective-C 的 API(包含零碎框架和你自定义的代码),你也能够在 Objective-C中 应用 Swift 的 API。这种兼容性使 Swift 变成了一个简略、不便并且弱小的工具集成到你的 Cocoa 利用开发工作流程中。上面通过一个案例演示,实现Swift与Object-C的混合编程。 作为一个开发者,有一个学习的气氛跟一个交换圈子特地重要,这有个iOS交换群:642363427,不论你是小白还是大牛欢送入驻 ,分享BAT,阿里面试题、面试教训,探讨技术! 步骤一:创立工程文件,名为Person。留神抉择编程语言为Swift。 步骤二:接下来就是要实现OC跟Swift的混合编程啦!首先创立一个Person类将他退出到工程中,语言选择为:Objective-C 步骤三:单击Finsh按钮,会呈现下图中的提示框,此处单击YES,零碎会主动生成桥接文件。 这是能够看到,零碎曾经创立出一个名为Person-Bridging-Header.h文件啦!,而后选中该文件将#import "Person.h"蕴含进去 这是咱们拷贝下零碎创立的桥接文件名,在工程中进行搜寻,能够看到配置文件 步骤四:Person类创立好后,咱们先不必去写代码,接下来再去创立一个House类,不过此类是Swift语言编写的。 在House类中,定义成员变量,初始化办法,以备Person类调用。 为避免前期,连贯时无奈应用,此处对该文件进行编译,如下图。 步骤五:剩下来要做的工作就是编写代码啦!手写在Person类中应用前向申明调用House,而后申明几个成员变量, 为之后测试做筹备,在Person.m文件中去重写description办法,下图中的选中局部,是零碎桥接时生成的文件。 步骤六:在控制器中应用Person和House 步骤七:打印输出后果

October 21, 2020 · 1 min · jiezi

关于objective-c:iOS14剪切板弹提示一探究竟附淘宝实现方法分析和demo

随着iOS 14的公布,剪切板的滥用也被大家所通晓。只有是APP读取剪切板内容,零碎都会在顶部弹出揭示,而且这个揭示不可能敞开。这样,大家在应用APP的过程中就可能看到哪些APP应用了剪切板。 正好咱们本人的利用也应用了剪切板,降级了iOS 14之后弹的着实让人心烦。就想着怎么解决一下,翻了一下UIPasteboard的文档,发现相干的内容并不多。读取UIPasteboard的string、strings、URL、URLs、image、images、color、colors的时候会触发零碎提醒。应用hasStrings、hasURLs、hasImages、hasColors等办法的时候不会触发零碎提醒。那么思路就是尽可能少的去调用会触发零碎提醒的办法,依据其余办法去判断的确须要读取的时候再去调用那些办法。依据咱们本人的状况,只有判断hasStrings为YES就去读取,又不能清剪切板,其实还是有点不尽人意,而后又看到这个属性: @property(readonly, nonatomic) NSInteger changeCount;The number of times the pasteboard’s contents have changed.Whenever the contents of a pasteboard changes—specifically, when pasteboard items are added, modified, or removed—UIPasteboard increments the value of this property. After it increments the change count, UIPasteboard posts the notifications named UIPasteboardChangedNotification (for additions and modifications) and UIPasteboardRemovedNotification (for removals). These notifications include (in the userInfo dictionary) the types of the pasteboard items added or removed. Because UIPasteboard waits until the end of the current event loop before incrementing the change count, notifications can be batched. The class also updates the change count when an app reactivates and another app has changed the pasteboard contents. When users restart a device, the change count is reset to zero.而后就又加了一个条件,记录一下真正读取剪切板时的changeCount,如果下次读取的时候没有发生变化则不读取。这样一来成果就好多了,利用运行生命周期内,基本上只会弹出一次提醒。 ...

September 29, 2020 · 2 min · jiezi

关于objective-c:Swift语法全面解析

Swift介绍 Swift 是一门开发 iOS, macOS, watchOS 和 tvOS 利用的新语言。 Swift是一种平安,疾速和互动的编程语言。 Swift反对代码预览(playgrounds),这个个性能够容许程序员在不编译和运行应用程序的前提下运行 Swift 代码并实时查看后果。 Swift 通过采纳古代编程模式来防止大量常见编程谬误: 变量始终在应用前初始化。查看数组索引超出范围的谬误。查看整数是否溢出。可选值确保明确解决 nil 值。内存被主动治理。错误处理容许从意外故障管制复原。根底局部 常量和变量 申明常量和变量, 常量和变量必须在应用前申明,应用 let 来申明常量,应用 var 来申明变量。 示例: let maximumNumberOfLoginAttempts = 10 var currentLoginAttempt = 0 // 类型注解 var welcomeMessage: String 正文 单行正文双正斜杠(//), 多行正文(/* 多行的 */)。 Swift 的多行正文能够嵌套在其它的多行正文之中。 示例: // 这是一个正文 /* 这也是一个正文, 然而是多行的 */ /* 这是第一个多行正文的结尾 /* 这是第二个被嵌套的多行正文 */ 这是第一个多行正文的结尾 */ 分号 Swift 并不强制要求你在每条语句的结尾处应用分号(;)。 同一行内写多条独立的语句必须用分号分隔。 ...

August 26, 2020 · 16 min · jiezi

关于objective-c:ObjectiveC之数据存储漫谈

存储形式介绍NSKeyedArchiver: 采纳归档的模式来保留数据沙盒中;NSUserDefaults:偏好设置数据存到沙盒的Library/Preferences目录(实质是plist);Write写入形式: 永恒保留在磁盘中;采纳SQLite等数据库来存储数据。1.NSKeyedArchiver:(归档)采纳归档的模式来保留数据,该数据对象须要恪守NSCoding协定,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:办法。 前一个办法通知零碎怎么对对象进行编码,而后一个办法则是通知零碎怎么对对象进行解码。 毛病:归档的模式来保留数据,只能一次性归档保留以及一次性解压。所以只能针对小量数据,而且对数据操作比拟蠢笨,即如果想改变数据的某一小部分,还是须要解压整个数据或者归档整个数据。 注: initWithCoder什么时候须要调用[super initWithCoder:]• initWithCoder原理:只有解析文件就会调用,xib,storyboard都是文件,因而只有解析这两个文件,就会调用initWithCoder。• 因而如果在storyboard应用自定义view,重写initWithCoder办法,肯定要调用[super initWithCoder:],因为只有零碎才晓得怎么解析storyboard,如果没有调用,就解析不了这个文件。2.NSUserDefaults:(偏好设置,实质是plist)用来保留应用程序设置和属性、用户保留的数据。用户再次关上程序或开机后这些数据依然存在。 NSUserDefaults能够存储的数据类型包含:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其余类型,则须要转换为后面的类型,能力用NSUserDefaults存储。 益处:1.不须要关怀文件名 2.疾速做键值对存储害处: 能及时存储,须要做同步操作,把内存中的数据同步到硬盘上底层:就是封装了一个字典 沙盒构造剖析:利用程序包:蕴含了所有的资源文件和可执行文件。Documents:保留利用运行时成成的须要长久化的数据,iTunes同步设施时会备份该目录。(例如,游戏利用可将游戏存到保留在该目录。大型数据不能寄存在这里,一旦寄存,iOS审核不会通过)tmp:保留利用运行时所需的长期数据,应用结束后再将相应的文件从该目录删除。利用没有运行时,零碎也可能会革除该目录下的文件。iTunes同步设施时不会备份该目录。Library/Caches:保留利用运行时生成的须要长久化的数据,iTunes同步设施时不会备份该目录。个别存储体积大、不须要备份的非重要数据。(个别把缓存下载好的文件放在这里)Library/Preference:保留利用的所有偏好设置,iOS的settings(设置)利用会在该目录中查找利用的设置信息。iTunes同步设施会备份该目录。注:在iOS7之前,默认不会马上跟硬盘同步,能够调用[userDefaults synchronize]; 同步操作3. Write写入形式:永恒保留在磁盘中。4. 采纳数据库来存储数据。4.1 SQLiteSQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就反对了SQLite,在应用时,只须要退出 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。然而,原生的SQLite API在应用上相当不敌对,在应用时,十分不便。 4.2 FMDB什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的形式封装了SQLite的C语言APIFMDB的长处 应用起来更加面向对象,省去了很多麻烦、冗余的C语言代码 比照苹果自带的Core Data框架,更加轻量级和灵便 提供了多线程平安的数据库操作方法,无效地避免数据凌乱FMDB有三个次要的类FMDatabase 一个FMDatabase对象就代表一个独自的SQLite数据库 用来执行SQL语句FMResultSet 应用FMDatabase执行查问后的后果集FMDatabaseQueue 用于在多线程中执行多个查问或更新,它是线程平安的通过指定SQLite数据库文件门路来创立FMDatabase对象 //取得数据库文件门路 NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];NSString *fileName=[doc stringByAppendingPathComponent:@"user.sqlite"]; FMDatabase *db = [FMDatabase databaseWithPath:path];if (![db open]) { NSLog(@"数据库关上失败!");}执行更新在FMDB中,除查问以外的所有操作,都称为“更新” create、drop、insert、update、delete等 应用executeUpdate:办法执行更新- (BOOL)executeUpdate:(NSString*)sql, ...- (BOOL)executeUpdateWithFormat:(NSString*)format, ...- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments//示例[db executeUpdate:@"UPDATE t_user SET age = ? WHERE name = ?;", @20, @"Jack"]执行查问 ...

August 12, 2020 · 2 min · jiezi

关于objective-c:ObjectiveC之runtime漫谈

runtime简介因为objective-c是一门动静语言,也就是说只有编译器是不够的,还须要一个运行时零碎(runtime system)来执行编译后的代码。这是整个objective-c运行框架的一块基石。runtime简称运行时。其中最次要的就是音讯机制。对于编译期语言,会在编译的时候决定调用哪个函数。对于OC的函数,是动静调用的,在编译的时候并不能决定真正调用哪个函数,只有在运行时才会依据函数的名称找到对应的函数来调用。runtime的作用Objc 在三种层面上与 Runtime 零碎进行交互: 1. 通过 Objective-C 源代码 2. 通过 Foundation 框架的 NSObject 类定义的办法 3. 通过对 Runtime 库函数的间接调用runtime源码苹果和GNU各自保护一个开源的runtime版本,这两个版本之间都在致力的保持一致。 都是运行时的头文件,其中次要应用的函数定义在message.h和runtime.h这两个文件中。通过 Foundation 框架的 NSObject 类定义的办法Cocoa 程序中绝大部分类都是 NSObject 类的子类,所以都继承了 NSObject 的行为。(NSProxy 类是个例外,它是个形象超类)-class办法返回对象的类;-isKindOfClass: 和 -isMemberOfClass: 办法查看对象是否存在于指定的类的继承体系中(是否是其子类或者父类或者以后类的成员变量);-respondsToSelector: 查看对象是否响应指定的音讯;-conformsToProtocol:查看对象是否实现了指定协定类的办法;-methodForSelector: 返回指定办法实现的地址。通过对 Runtime 库函数的间接调用Runtime 零碎是具备公共接口的动静共享库。头文件寄存于/usr/include/objc目录下,这意味着咱们应用时只须要引入objc/Runtime.h头文件即可。 许多函数能够让你应用纯 C 代码来实现 Objc 中同样的性能。除非是写一些 Objc 与其余语言的桥接或是底层的 debug 工作,你在写 Objc 代码时个别不会用到这些 C 语言函数。对于公共接口都有哪些,前面会讲到。我将会参考苹果官网的 API 文档。 Runtime的术语的数据结构SEL它是selector在 Objc 中的示意(Swift 中是 Selector 类)。selector 是办法选择器,其实作用就和名字一样,日常生活中,咱们通过人名分别谁是谁,留神 Objc 在雷同的类中不会有命名雷同的两个办法。selector 对办法名进行包装,以便找到对应的办法实现。它的数据结构是: typedef struct objc_selector *SEL;咱们能够看出它是个映射到办法的 C 字符串,你能够通过 Objc 编译器器命令@selector() 或者 Runtime 零碎的 sel_registerName 函数来获取一个 SEL 类型的办法选择器。 ...

August 10, 2020 · 5 min · jiezi

关于objective-c:synthesize

公布于 2018/08/28 18:10,搬家到思否。Xcode4时,@property只能生成getter、setter办法的申明; 从Xcode5开始,@property 能够主动生成_propertyName成员变量和getter、setter办法的申明和实现。默认状况下,getter、setter办法作用于_propertyName变量。 然而,当同时重写getter和setter两个办法的时候,实现了齐全的自定义实现,无奈对应到默认的变量_propertyName,_propertyName就有效了,须要手动定义一个变量或者应用@synthesize指定一个变量来绑定到属性上。 一、手动定义变量 Girl.h #import <Foundation/Foundation.h>@interface Girl : NSObject@property (nonatomic, copy) NSString *name;@property (nonatomic, copy) NSString *boyFriend;@endGirl.m #import "Girl.h"@implementation Girl/* *************** MARK: 办法一 *************** */{ NSString* _name; //手动注册变量}- (NSString *)name{ if (!_name) { _name = @"zhangli"; } return _name;}- (void)setName:(NSString *)name{ _name = name;}@end如果不去手动定义一个变量,那么独自写getter或setter没有问题,然而同时重写就会报错了。 二、@synthesize /* *************** MARK: 办法二 *************** */@synthesize boyFriend = man; //应用@synthesize,将属性对应于变量- (NSString *)boyFriend { if (!man) { man = @"Jerod"; } return man;}- (void)setBoyFriend:(NSString *)boyFriend{ man = boyFriend;}属性boyFriend本来是对应于_boyFriend变量的,这里通过@synthesize扭转了属性、getter、setter对应的变量。(这点很有用途,比方能够在子类批改父类中readonly属性的值。) ...

July 27, 2020 · 1 min · jiezi

关于objective-c:CGAffineTransformMakeabcdtxty-矩阵运算原理

CGAffineTransformMake(a,b,c,d,tx,ty) a d 缩放, b c 旋转, tx ty 位移 (x , y) -> (x' , y') 的公式 x' = ax + cy + tx y' = bx + dy + ty矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty;};CGAffineTransform CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty); 为了把二维图形的变动对立在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵示意,其中第三列总是(0,0,1),用来作为坐标系的规范。所以所有的变动都由前两列实现。 以上参数在矩阵中的示意为: 运算原理:原坐标设为(X,Y, 1) | a b 0 |(X,Y, 1) ⅹ | c d 0 | = (aX + cY + tx , bX + dY + ty , 1) ; | tx ty 1 |通过矩阵运算后的坐标(aX + cY + tx, bX + dY + ty, 1) 咱们比照一下可知: ...

July 27, 2020 · 1 min · jiezi