公司怎么注册网站免费,金属网站模板,江苏省 建设 注册中心网站,长春做网站推广的公司iOS应用是如何启动以及如何优化 pre-main阶段 加载动态链接器dyld到App进程 加载动态库#xff08;包括所依赖的所有动态库#xff09; Rebase 修正内部的指针指向 Bind 修正外部指针指向 初始化Objective C Runtime 包括oc的类、分类的注册#xff0c;selector唯一性检查等… iOS应用是如何启动以及如何优化 pre-main阶段 加载动态链接器dyld到App进程 加载动态库包括所依赖的所有动态库 Rebase 修正内部的指针指向 Bind 修正外部指针指向 初始化Objective C Runtime 包括oc的类、分类的注册selector唯一性检查等 初始化代码调用Oc类和分类的load方法构造器函数的调用用attribute((constructor))修饰的函数、创建C静态全局变量等 执行main函数后调用didFinishLaunching方法完成初始化 对于pre-main阶段的耗时测量方法在 Xcode 中 Edit scheme - Run - Auguments 将环境变量DYLD_PRINT_STATISTICS 设为1 。之后控制台会输出耗时。DYLD_PRINT_STATISTICS_DETAILS 建议应用的启动时间控制在400ms之下并且在20s内启动否则系统会kill app。 一般是优化main函数阶段大多数的耗时是在自己写的代码里 优化方法 减少自定义的动态库数量合并动态库官方建议不超过6个。因为动态库的加载方式比静态库慢。如果必须依赖动态库则把多个非系统的动态库合并成一个动态库。静态库是在编译时将库的代码打包到可执行程序中动态库则是在运行时动态加载到程序中的。 减少Objective-C类,分类和Selector的个数类似功能尽量合并 减少使用构造器函数 减少使用oc的load 减少c静态全局变量 压缩资源图片因为在启动加载时会加载资源图片进行IO操作。所以图片小加载速度也会显著提升。 删除无用的方法和类多用Swift Structs因为Swfit Structs是静态分发的 延迟初始化那些不必要的UIViewController。 didFinishLaunching中耗时操作的优化 类和方法名不要太⻓。 Load和initialize的不同 调用顺序不同以main函数为分界load方法在main函数之前执行initialize在main函数之后执行。 子类中没有实现load方法子类不会调用父类的load方法而子类如果没有实现initialize方法的话也会自动调用父类的initialize方法。 load方法是在类被装在进来的时候就会调用initialize在实例化对象的时候调用并且只会调用一次是懒加载模式如果这个类一直没有使用就不回调用到initialize方法。 property 的本质是什么 property的本质是实例变量ivar 存取方法 即 property ivar getter setter 属性” (property)作为 Objective-C 的特性主要用于封装对象中的数据。 Objective-C 对象数据保存为实例变量。实例变量一般通过“存取方法”来访问。 getter读取setter写入。 property中有哪些属性关键字/ property 后面可以有哪些修饰符 atomic、nonatmoic、readonly、readwrite、assign、weak、strong、copy 什么情况使用 weak 关键字相比 assign 有什么不同 什么情况使用 weak 关键字 循环引用的时候,比如: delegate 代理属性 xib的IBOutlet 控件属性一般也使用 weak 不同点 assigin 可以修饰非 OC 对象比如简单数据类型 int bool,weak 必须用于 OC 对象, weak 是弱引用被weak修饰的对象引用计数不会加1 不会产生野指针。weak修饰的对象释放后指针会自动被置nil是安全的。 assign 修饰基本数据类型是安全的。如果修饰对象会产生野指针修饰的对象释放后指针不会自动置空。 所以一般都是用 assign 来修饰基本类型weak 来修饰对象 __weak __block 通过 __weak 弱引用来打破循环引用。 __block__block修饰的变量可以修改。在代码块中会被retainARC__weak__weak修饰的变量不可以修改。不会在block代码块中被retain __block不能修饰全局变量、静态变量static block本质和说明 block闭包本质上也是对象是一段代码块是带有自动变量的匿名函数可以精简代码减少耦合 block使用的时候可以作为变量使用可以作为方法参数也可以做为属性或实例变量 他有个特性叫变量捕获机制block内部会捕捉外部变量auto局部变量直接捕获值static修饰的变量捕获指针全局变量不捕获 Auto局部变量我们平时写的局部变量默认就带着 auto (自动变量离开作用域就销毁) 在 Block 内部修改 外部变量 需要用 __block 使用block时要特别注意循环引用避免互相持有对方的强引用导致它们无法被释放从而造成内存泄漏。 __weak来打破循环引用。 block内部如何修改变量的值 这个问题一般问的是修改局部变量的值因为全局变量直接可以访问到不存在修改不了的情况 如何修改局部变量的值第一种直接使用static修饰。第二种局部变量改为全局变量。第三种使用__block修饰变量 注意只要不对变量/对象 的值进行修改 就不要去使用__block block分类 .引用全局变量、全局静态变量、局部静态变量Block 在全局区属于 GlobalBlock b.引用普通外部变量用 copystrong 修饰的 Block 就存放在堆区属于 MallocBlock 用 weak 修饰的Block 存放在栈区属于 StackBlock RunLoop 事件驱动/事件循环 的一个对象。没有消息需要处理时休眠有消息需要处理时唤醒 main函数为什么可以一直运行而不退出内部维护了一个主线程RunLoop 1、RunLoop与NSTimer 一个比较常见的问题滑动tableView时定时器不生效因为在滑动时会切换RunLoop的mode不在defaultmode下了所以失效可以放到commonmode下解决。commonMode是否使用过怎样理解相当于defaultmode和TrackingMode的集合 怎样保证子线程数据回来更新UI的时候不打断用户的滑动操作 将更新UI事件放在主线程的NSDefaultRunLoopMode上执行滑动是在UITrackingRunLoopMode上执行 一个线程对应一个runloop主线程自动运行runloop但是子线程的runloop需要手动运行 怎样实现一个常驻线程 每次开辟子线程都会消耗cpu在需要频繁使用子线程的情况下会消耗大量的cpu而且创建线程都是任务执行完成之后也就释放了不能再次利用 向子线程runloop中添加空定时器保持唤醒 runtime 运行时 动态属性 objc_setAssociatedObject objc_getAssociatedObject 动态创建类 objc_allocateClassPair objc_registerClassPair 交换方法 swizzlingInstanceMethodInClass 例子Scrollview的头部空白 解决方法是设置其contentInsetAdjustmentBehavior属性为UIScrollViewContentInsetAdjustmentNever。但对于现存的项目来说挨个修改工作量无疑是巨大的也容易出问题。这时候就用到Runtime了用runtime来交换其初始化方法来统一设置这个属性就可以得到解决。 获取类的一些信息包括属性列表方法列表成员变量列表和遵循的协议列表 //1.获取成员变量列表class_copyIvarList //2.获取属性列表class_copyPropertyList //3.获取方法列表class_copyMethodList //4.获取协议列表class_copyProtocolList 设计模式 工厂模式 将创建对象的方法进行封装调用即可创建对象 单例模式 保证一个类仅有一个实例并提供一个访问它的全局访问点。 UIApplication userdefault dispatch_once private static let test .init 代理模式 UITableViewDatasource UITableViewdelegate uitexttfielddelegate等适用于告知代理对象进行事件处理 观察者模式KVO 添加监听发生变化时触发监听方法使用结束后移除监听。一般是通过notificationcenter addobserver,他是一个单例一对多的消息广播模式 kvc键值编码 架构模式 Mvc mvvm MVC 通过controller来协调model和view之间的交互将代码变得模块化 mvvm在mvc的基础上衍生出了viewmodel来处理model的数据复用性更高ViewModel 处理 网络请求、数据逻辑和缓存读写等等 微服务架构特别适合大型的项目可以将模块单独拆分成不同的project然后嵌入到项目中kite有微服务架构的思想 设计原则 单一职责原则强调一个类或模块只负责一项功能例如CALayer负责动画和视图显示而UIView则提供显示内容和事件处理。 开闭原则要求对修改关闭对扩展开放例如通过使用category来实现功能的扩展。要考虑到后续的扩展性而不是在原有的基础上来回修改 依赖倒置原则指出抽象不应该依赖于具体实现而实现应该依赖于抽象这有助于提高代码的灵活性和可维护性。 里氏替换原则表明子类必须能够替换其基类而不会引起程序行为的变化这在面向对象编程中尤为重要。 接口隔离原则使用多个专门的协议来做接口隔离、而不是一个庞大臃肿的协议 UITableviewDelegate UITableViewDataSource 迪米特法则也称为最少知识原则强调一个对象应当对其他对象尽可能少的依赖以减少类与类之间的耦合。实现高聚合、低耦合 App的优化 启动过程耗时 优化内存泄露包括循环引用 优化闪退或卡死 优化过大图片、冗余文件 控制ipa包体积 页面流畅度 cocoapod Swift Package Manager Alamofirehttp网络请求框架 要在Alamofire之后解析JSON定义一个遵循Codable协议的Swift结构体或类然后使用 JSONDecoder可以设置 CodingKeys 11、SnapKitautoLayout自动布局框架 12、Kingfisher喵神王巍写的一款关于图片下载、缓存的框架。灵感取自OC里面的SDWebImage 4、RxSwift函数响应式编程框架是ReactiveX的swift版本可以简化异步操作和事件/数据流 8、ObjectMapper把json对象映射为model对象 不可变对象的copy是浅复制mutablecopy是深复制 可变对象的copy与mutablecopy都是深复制