自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(86)
  • 收藏
  • 关注

原创 【iOS】——YYModel源码总结

YYModel主要用于将JSON数据转换为模型对象,以及将模型对象转换为字典的库。JSONModelModelJSONYYModel的容错性更好,它会自动进行错误类型检查,如果检查到不匹配的类型会自动赋值为nil。YYModel无侵入性,它采用类别的方式来实现功能,不同于JSONModel需要模型类继承于JSONModel类。

2024-09-20 20:02:59 1486

原创 【iOS】——JSONModel源码

JSONModel框架的作者允许开发者自定义错误阻止模型的转换使用validate方法if (!return NO;*error = [NSError errorWithDomain:@"未成年!return NO;return YES;

2024-09-19 22:00:10 1243

原创 【iOS】——应用启动流程

广义上的启动是点击图标到首页数据加载完毕狭义上的启动是点击图标到启动图完全消失的第一帧启动的最佳时间是400ms以内,因为从点击图标到显示Launch Screen,到Launch Screen消失这段时间是400ms。启动时间不可以大于20s,否则会被系统杀掉起点:进程创建的时间终点:第一个是 Core Animation 提供的一种事务机制,把一组 UI 上的修改打包,一起发给 Render Server 渲染。

2024-09-13 11:27:21 1475

原创 【iOS】——渲染原理与离屏渲染

图像渲染流程大致分为四个部分:除了Application阶段由 CPU 负责,后续都是由GPU负责这个阶段具体指的就是图像在应用中被处理的阶段,此时还处于 CPU 负责的时期。在这个阶段应用可能会对图像进行一系列的操作或者改变,最终将新的图像信息传给下一阶段。这部分信息被叫做图元(primitives)进入这个阶段之后,以及之后的阶段,就都主要由 GPU 负责了。此时 GPU 可以拿到上一个阶段传递下来的图元信息,GPU 会对这部分图元通过顶点着色器、形状装配、几何着色器进行处理,之后输出新的图元。这一系列

2024-09-08 09:26:09 1239

原创 【iOS】——分类拓展关联对象

分类可以用来为类动态的添加方法,通过关联对象还能动态添加属性分类默认只能声明属性不会生成成员变量和对应的get和set方法分类也用于模块化设计分类是在运行期生成,扩展是类的一部分在编译期生成关联对象的API的实现都是通过操作AssociationsManager、AssociationsHashMap、ObjectAssociationMap、ObjcAssociation来实现Category的方法会“覆盖”掉原来类的同名方法?Category。

2024-08-28 19:42:46 1076 1

原创 【iOS】——响应者链和事件传递链

如果当前这个view是控制器的view,那么控制器就是上一个响应者;如果当前这个view不是控制器的view,那么父控件就是上一个响应者。传递链:有系统向最上层view传递,->window->root view-> … ->first view响应连:由最基础的view向系统传递,first view->super view-> … ->->window->->如果我们不想让某个视图响应事件,只需要重载 PointInside:withEvent:方法,让此方法返回NO就行了.

2024-08-17 20:13:06 1072

原创 【iOS】——AutoReleasePool底层原理及总结

自动释放池是由以双向链表的方式实现的,每一个所占内存大小为4096字节,其中56字节用于存储结构体中的成员变量。autoreleasepool在初始化时,内部是调用方法autoreleasepool在调用析构函数释放时,内部是调用方法入栈(push)在页中压栈普通对象主要是通过next指针递增进行的当没有pool,即只有空占位符(存储在tls中)时,则创建页,压栈哨兵对象。

2024-08-06 20:08:25 1189 1

原创 【iOS】——GCD总结

此时就形成了主队列中的任务需要等待将任务添加到队列的这个操作的任务执行完才能进行,而将任务添加到队列这个操作需要等待主线程上的任务执行完才能进行,形成了主队列和主线程相互等待的局面,造成了死锁。如果是同步执行之后再进行异步操作,虽然开启了新线程,但是同步执行的任务在开启新线程之前就已经全部执行完了,这个新线程只负责处理异步操作中的任务,也就是同步执行的还是顺序,异步执行的是乱序。GCD中的队列有串行队列和并发队列,都是采用FIFO原则,也就是创建的新任务总是在队尾,执行的当前任务总是从队头开始。

2024-08-03 20:53:49 807

原创 【iOS】——NSOperation和NSOperationQueue学习总结

首先需要创建一个继承于NSOperation的子类,接着在该类的实现部分重写main方法,我们不需要管理操作的状态属性和isFinished。当main执行完返回的时候,这个操作就结束了。if (!i < 2;i++) {@end//1.创建CustomOperation对象// 2.调用 start 方法开始执行操作[op start];可添加完成的代码块,在操作完成后执行。添加操作之间的依赖关系,方便的控制执行顺序。设定操作执行的优先级。可以很方便的取消或暂停一个操作的执行。

2024-08-02 19:56:30 1213

原创 【iOS】——NSThread

NSThread提供了一个面向对象的接口来创建和管理线程,相比底层的pthreadNSThread提供了更高级别的抽象,使得线程的创建和管理更加简单和安全。一个NSThread对象代表一个线程,使用比较简单,但是需要手动管理线程的生命周期、处理线程同步等问题。

2024-08-01 15:05:07 851

原创 【iOS】——锁

假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞 (blocking),Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。当一个线程试图获取一个已经被占用的锁时,它不会排队等待,而是立即返回,这意味着它可能在其他等待的线程之前再次尝试获取锁。如果锁已经被占用,其它试图获取锁的线程会等待,直到锁重新可用。

2024-08-01 11:42:59 531

原创 【iOS】——持久化

因为plist文件不能够保存自定义对象。如果一个字典中保存有自定义对象,如果把这个对象写入到文件当中,它是不会生成 plist文件的。如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复。

2024-07-30 19:26:47 1187

原创 【iOS】——KVC和KVO

key的值必须正确,如果拼写错误,会出现异常。当key的值是没有定义的,valueForUndefinedKey:这个方法会被调用,如果你自己写了这个方法,key的值出错就会调用到这里来。因为类可以反复嵌套,所以有个keyPath的概念,keyPath就是用.号来把一个一个key链接起来,这样就可以根据这个路径访问下去。NSArray/NSSet等都支持KVC。可以通过KVC访问自定义类型的私有成员。

2024-07-30 10:55:20 1286

原创 【iOS】——通知机制及底层原理

注册通知在同步通知中存储是以name和object为维度的,即判定是不是同一个通知要从name和object区分,如果他们都相同则认为是同一个通知,后面包括查找逻辑、删除逻辑都是以这两个为维度的。通过name和object将通知存储划分为三种结构:named表(name存在)、nameless表(name不存在)、wildcard链表(name和object都不存在)在通知的存储过程并没有做去重操作,这也解释了为什么同一个通知注册多次则响应多次。

2024-07-26 22:28:40 1223

原创 【iOS】——Block循环引用

此时self持有block,block弱引用self,弱引用会自动变为nil,强持有中断,所以不会引起循环引用。weakSelf被强引用了就不会自动释放,因为strongWeak只是一个临时变量,它的声明周期只在block内部,block执行完毕后,strongWeak就会释放,而弱引用weakSelf也会自动释放。在上面代码中,person对象强持有block对象,在block语法中,block对象又强持有person对象,此时达成互相强持有,谁也无法释法谁,造成循环引用。对person产生强引用。

2024-07-25 22:06:54 1182

原创 【iOS】——Block底层实现和捕获机制

Block的本质是一个对象,其内部的第一个成员是isa指针,通过内部的FuncPtr指针指向实际执行的函数,也就是Block中花括号里面的代码内容。Block只会捕获自己需要使用的自动变量并将其保存进了Block的结构体实例中,也就是Block自身中。Block捕获普通的局部变量只是通过构造函数将它的值传递进了Block的结构体实例中的成员,因此不能在Block内部修改值,并且在Block外修改的值也不会影响Block捕获时的值。

2024-07-25 16:57:52 1065

原创 【iOS】——Block概要和使用规范

调用Block的时候会去访问Block结构体中的FuncPtr指针,因为Block为空,所以此时的FuncPtr指针所指的位置是无效的,当访问这个无效的地址的时候就会报错

2024-07-25 11:58:17 680

原创 【iOS】——属性关键字的底层原理

可以看到atomic为yes的时候,对应属性的set、get方法用到了spinlock_t锁,保证了set、get方法的线程安全,但是并不能保证其他操作的线程安全,比如对属性进行进行release操作。, 此函数会根据提供的参数执行属性值的设置,包括处理原子性操作和拷贝行为。如果shouldCopy=MUTABLE_COPY 那么 copy = NO,mutableCopy = YES。如果shouldCopy=0 那么 copy = NO,mutableCopy = NO。是实例变量的偏移量;

2024-07-23 19:29:11 1219

原创 【iOS】——属性关键字

NSMutableArray用copy修饰会出现什么问题?出现调用可变方法不可控问题,会导致程序崩溃。对于可变对象使用copy关键字会进行深拷贝,返回一个不可变的对象,对不可变的对象调用可变方法就会crash2.copy关键字影响了对象的可变和不可变属性吗?可变对象(mutable)copy和mutableCopy都是深拷贝不可变对象(immutable)的copy是浅拷贝,mutableCopy是深拷贝。

2024-07-23 15:48:42 536

原创 【iOS】——SideTable

SideTablesde的实质类型是存储SideTable的StripedMap。在StripedMap类中有定义存储sidetable的最大数量,所以每个SideTablesdes可以对应多个对象,而每个对象对应一个sidetable。iphone 中 SideTables() 本质是返回一个 SideTableBuf 对象,该对象存储 8 个 SideTable;因为涉及到多线程和效率的问题,必定不可能只使用一个 SideTable 来存储对象相关的引用计数器和弱引用;

2024-07-22 19:29:55 1343

原创 【iOS】——weak底层原理

weak的本质其实是哈希表,用所引用的对象的地址作为key,用weak指针的地址集合作为value。weak的实现原理如下:初始化:runtime会调用方法(这是接口方法最值调用storeWeak),初始化一个新的weak指针指向对象的地址。添加引用函数会调用函数,的作用是更新指针指向,创建对应的弱引用表。释放:调用函数(也是接口函数,最终调用函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,清理对象的记录。

2024-07-22 16:50:39 600

原创 【iOS】——探究isKindOfClass和isMemberOfClass底层实现

判断该对象是否为传入的类或其子类的实例分为类方法和实例方法,相同点都是首先判断调用者的isa指针指向的对象是否和传入的cls对象相同,如果不相同则沿着继承链获取调用者的父类的isa指针接着判断其指向的对象和传入的cls对象相同。如果相同则返回YES,否则一直沿着继承链找直到tcls为nil退出循环并返回NO。至于tcls为什么能为nil呢,因为任何OC对象沿着继承链向上都会到根类NSObject类而NSObject类的Superclass为nil说完了相同点下面说下不同点,在OC中实例对象的isa指针指向

2024-07-20 10:42:00 1137

原创 【iOS】——消息传递底层实现

OC在编译时会根据方法的名字(包括参数序列),生成一个用来区分这个方法的唯一的一个ID,这个ID就是SEL类型的。如果在当前类对象的缓存中找到了转发的条目(imp == forward_imp),表示在父类的缓存中找到了转发的方法实现。第一 个参数代表接收者也就是方法调用者,第二个参数代表方法选择器(SEL 是选择子的类型)也就是方法的名字,后续参数就是消息中的 那些参数,其顺序不变。最后,在循环结束后,会根据需要将找到的方法实现缓存到类对象的缓存中,然后解锁运行时锁,并根据需要返回找到的方法实现或空值。

2024-07-19 15:14:56 1328

原创 【iOS】——内存分区

全局区和静态区在程序启动时由系统分配,并在程序结束时由系统释放。栈空间分静态分配和动态分配两种:静态分配是编译器完成的,比如自动变量(auto)的分配。全局静态变量与全局变量 其实本质上是没有区别的,只是存在修饰区别,一个static让其只能内部使用,一个extern让其可以外部使用。不管实例方法还是类方法都可以访问和修改静态变量,并且外部类无法调用静态变量,定义后只会指向固定的指针地址,供所有对象使用,节省空间。:没有用extern在.h中修饰的变量,仅定义在.m中让该变量只能在该类使用。

2024-07-18 11:58:52 958

原创 【iOS】——内存对齐

内存对齐指的是数据在内存中的布局方式,它确保每个数据类型的起始地址能够满足该类型对齐的要求。apple系统为了防止一切的容错,采用的是16字节对齐的内存,主要是因为采用8字节对齐时,两个对象的内存会紧挨着,显得比较紧凑,而16字节比较宽松,利于苹果以后的扩展。后续的数据成员将被放置在它们各自自然对齐的地址上,即如果成员是4字节的整型,它将被放置在4字节对齐的位置;的顺序定义的,根据内存对齐规则来计算结构体内存大小,需要增加有较大的内存padding即内存占位符,才能满足内存对齐规则,

2024-07-18 11:56:52 751

原创 【iOS】——编译链接和动态链接器

计算机语言分为机器语言:汇编语言,高级语言。可以将高级语言分为两种:1,编译语言和解释型语言(直译式语言)。编译型语言(一次性翻译)编译型语言的程序只要经过编译器编译之后,每次运行程序都可以直接运行如oc,swift等解释型语言(逐步进行解释执行)解释语言编写的程序在每次运行时都需要通过解释器对程序进行动态解释和执行,如php,javascript等动态链接器通常指的是dyld。dyld是它负责处理程序和动态库(dylib,动态链接库)之间的链接操作。dyld。

2024-07-18 10:16:13 798

原创 【iOS】——TaggedPointer

在为了改进从32位CPU迁移到64位CPU的内存浪费和效率问题,在64位CPU环境下,引入了。旨在提高内存效率和运行性能,尤其针对小的、频繁使用的对象,如NSNumberNSDate, 和NSString等。在64位处理器上,每个指针占用8字节,而某些对象可能只包含少量数据,因此使用完整对象和指针来管理这些小对象可能造成不必要的内存消耗和性能开销。地址最低位也就是0位是TaggedPointer标志位第1-3位是类标志位第4-7位表示数据类型或字符串长度8-63位用来存储数据。

2024-07-17 19:38:52 1006

原创 【iOS】——MRC

内存管理的核心是引用计数器,用一个整数来表示对象被引用的次数,系统需要根据引用计数器来判断对象是否需要被回收。在每次 RunLoop 迭代结束后,都会检查对象的引用计数器,如果引用计数器等于 0,则说明该对象没有地方继续使用它了,可以将其释放掉。

2024-07-16 15:30:15 1294

原创 【iOS】——ARC源码探究

ARC的全称Auto Reference Counting. 也就是自动引用计数。使用MRC时开发者不得不花大量的时间在内存管理上,并且容易出现内存泄漏或者release一个已被释放的对象,导致crash。后来,Apple引入了ARC。使用ARC,开发者不再需要手动的retain/release/autorelease. 编译器会自动插入对应的代码,再结合Objective-C的runtime,实现自动引用计数。blockOC的对象,id, Class, NSError*等。

2024-07-16 15:22:36 1268

原创 【iOS】——Runtime学习

iOS的Runtime,通常称为Objective-C Runtime,是一个C语言库,包含了很多底层的纯C语言API。,它是Objective-C语言动态特性的基石。这个系统在程序运行时提供了一系列强大的功能,允许我们在应用运行过程中动态地操作类和对象,执行诸如检查和改变对象、交换方法实现、动态添加方法或属性等操作。高级编程语言想要成为可执行文件需要先编译为汇编语言再汇编为机器语言,机器语言也是计算机能够识别的唯一语言,但是OC并不能直接编译为汇编语言,而是要先转写为纯C语言再进行编译和汇编的操作,

2024-06-06 22:04:05 1389

原创 【iOS】——工厂设计模式

这种模式旨在为创建对象提供一个统一的接口,隐藏了创建对象的具体逻辑,使得客户端不需要知道所创建对象的具体类,从而降低了对象之间的耦合度,提高了代码的灵活性和可维护性。它为创建对象提供了一种灵活的方式,让子类来决定实例化哪一个类,从而实现了对象创建的延迟化和抽象化,增强了代码的扩展性和可维护性。车没了,该车的引擎和轮胎自然也没了。当系统中加入新产品时,不需要修改抽象工厂和抽象产品提供的接口,也无须修改客户端和其他的具体工厂和具体产品,而只要添加一个具体工厂和与其对应的具体产品就可以了,符合了“开-闭”原则。

2024-05-22 20:02:40 1197

原创 【iOS】——GCD再学习

Grand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更有效率。//让处理在后台线程中执行 dispatch async(queue , ^ {/**长时间处理*例如AR用画像识别*例如数据库访问*/ /*

2024-05-20 16:12:47 981

原创 【iOS】——RunLoop学习

一个线程一次只能执行一个任务,执行完毕后就会退出。do {//获取消息//处理消息} while (消息!= 退出)这种模型通常被称为Event Loop,Event loop 在很多系统和框架都有实现。例如:Node.js 的事件处理,Windows 程序的消息循环,而在macOS、iOS中就是Run Loop。简单的说RunLoop其实就是一种循环,通过这种循环得以让应用程序持续运行,让线程能随时处理事件,并在线程需要进行事件处理时忙起来,在不需要进行事件处理时闲下来。

2024-05-14 20:22:27 1305 2

原创 【iOS】——浅析CALayer

在官方文档中CALayer是管理基于图像的内容并允许您对该内容执行动画的对象。通俗来说就是在iOS中我们能看到的所有的UIView对象例如文本框、按钮、输入框等等之所以能够显示到屏幕上就是因为该UIView对象内部有一个图层专门用来显示,也就是CALayer对象,通过访问layer属性便可以访问它的图层。每当我们创建一个UIView对象时并将其添加到视图层级后,UIKit 会为其自动创建并关联一个 CALayer(RootLayer)。

2024-05-07 17:36:20 1227

原创 【iOS】——SDWebImage源码学习

SDWebImage是iOS中提供图片加载的第三方库,可以给UIKit框架中的控件比如UIImageView和UIButton提供从网络上下载和缓存的图片。它的接口十分简洁,如果给UIImageView控件添加图片可以使用如下代码//第一个参数是图片的URL第二个参数是占位图片加载失败时显示如果给UIButton添加图片可以使用如下代码//第一个参数是图片的URL,第二个参数是按钮状态,第三个参数是占位图片,加载失败时显示通过异步方式加载图片可以自动缓存到内存和磁盘中,并且可以自动清理过期的缓存。

2024-04-16 15:51:06 654

原创 【iOS】——Blocks

Blocks是C语言的扩充功能,并且可以用一句话来表示Blocks的扩充功能:Blocks是带有自动变量(局部变量)的匿名函数。匿名函数:Blocks是一种匿名函数,也就是没有特定名称的函数。它们可以在需要的地方定义和使用,而无需提前声明或命名。这使得Blocks非常灵活,可以作为参数传递给其他函数或方法,或者作为变量保存和执行。自动变量(局部变量):Blocks可以捕获其定义范围内的自动变量(也称为局部变量)。当一个Block被定义时,它会在其内部创建一个副本,用于在Block执行时访问该变量的值。

2024-03-18 19:46:43 1304 2

原创 【学习iOS高质量开发】——协议与分类

OC动态消息系统的工作方式决定了其不可能实现真正的私有方法或者私有实例变量。那么怎么实现私有变量和私有方法呢?这就要用到特殊的“class-continuation分类”了。“class-continuation分类”和普通的分类不同,他必须定义在其所接续的那个类的实现文件里,并且这个类没有名字。这样你就可以在其中定义你的私有方法和私有变量了,这样有什么好处呢?公共接口里本来就能定义实例变量。不过,把它们定义在“class-continuation分类”或“实现块”中可以将其隐藏起来,只供本类使用。

2024-02-19 12:30:00 1137

原创 【学习iOS高质量开发】——接口与API设计

所有对象均要初始化。初始化时,有些对象可能无须开发者向其提供额外信息,不过一般来说还是要提供的。以iOS的UI框架UIKit为例,其中有个类叫做UITableViewCell,初始化该类对象时,需要指明其样式及标识符,标识符能够区分不同类型的单元格。由于这种对象的创建成本较高,所以绘制表格时可依照标识符来复用,以提升程序效率。我们把这种可为对象提供必要信息以便其能完成工作的初始化方法叫做“全能初始化方法”。如果创建类实例的方法不止一种,那么这个类就会有多个初始化方法。

2024-02-19 05:33:57 1142

原创 【iOS】——使用ZXingObjC库实现条形码识别并请求信息

ZXing库是一个专门用来解析多种二维码和条形码(包括包括 QR Code、Aztec Code、UPC、EAN、Code 39、Code 128等)的开源性质的处理库,而ZingObjC库是它的一个移植版本。由于博主还没有真机进行调试,所以舍去了使用摄像头的一些方法,仅实现其最终识别结果的方法。

2024-02-07 10:51:54 2426

原创 【学习iOS高质量开发】——对象、消息、运行期

public@private@end@public@private@end那么新添加的实例变量就会代替原第一个位置实例变量的偏移量。这样的话,如果代码使用了编译器计算出来的偏移量,那么在修改类定义之后必须重新编译,否则就会出错。例如:某个代码库中的代码使用了一份旧的类定义。如果和其相链接的代码使用了新的类定义,那么运行时就会出现不兼容现象。OC把实例变量当作一种存储偏移量所用的“特殊变量”,交由“类对象”保管。

2024-01-21 17:32:58 1172 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除