00:00
那么首先第一点,为什么今天要给大家分享lo这个课的一个内容,因为我们最近调查了咱们学员,咱们逻辑教育VIP学员的一面的一个面试题啊,包括大厂相关的面试题,那么block在这一块占的一个比重还是比较大的,而且现在的block面试基本上是以堆栈,包括底层原理,包括它的拷贝,哎,作为先导的一个知识。那么我们来看一下今天这节课的一个内容,那么第一点就是我们block对于栈的一个探究,然后呢,顺便来看一下底层原理,那么这个底层原理我们主要明白两点,第一点它是一个结构体,底层是一个结构体,包括我们OC的对象是它底层也是一个结构体。那么然后呢,第二点我们要明白,如果block内部有一个函数的指针保存着我们写在block代码块里面的一个内容,然后呢,我们来学习一下block的三种类型,因为这三种类型是建立在我们判断这个堆栈,包括呢block怎么捕获变量的基础上,那么明白什么场景下会触发block的拷贝。
01:00
然后呢,Block循环以后产生的一个原因,以及怎么解决,那么面试题具体类型呢?我们来看一下block类别与内存相关的一个面题。那么站上的block能捕获变量吗?哎,堆上的block我们知道能捕获变量,那么站上的也能吗?那么第二点,站上的block与堆上的block使用上面有什么区别?哎,怎么去判断它的类型?然后呢,Copy修饰的一定是堆上的block吗?怎样触发这个block的copy,然后堆栈到底有什么区别?那么循环引用,哎,杠杆微课真的能解决这个循环引用啊,那么这个是咱们今天课程的一个主要内容,那么首先第一点我先上来给大家干一个什么事情呢?给大家出一道面试题,先给大家把大家镇住,吓唬住,那么这个面试题我们来看到这个地方。在这个viewd的log里面,我写了哎这么几句代码,那么我们从上往下看,那么首先第一点,我在这个地方是不是alo引了一个ns object对象。然后在这个地方我获到了的一个。
02:05
反应出是多少。正常的是不是我lo in之后应该是一吧,好,那么我再往后看,那么接下来被一个杠杠死strong修饰的这个strong block,那么哎,在里面使用了这个变量O之后,那么请问。这个地方打印出的是多少。给大家五秒钟的一个思考时间。五。二。有同学说是二啊,包括咱们的张同学,咱们的VIP同学也说是二好,那么接下来我们再往后看,那么这个地方我有一个杠杠未可修饰的一个week block。那么在这个block里面呢,我同样也去补货了,也去使用了这个我初始化的对象O,那么请问在这个地方它打印出的应该是多少呢?
03:03
这个地方是一个二,然后接下来他又在这里面就是用来五。三。二。一还有没有其他同学来我看一下,给大家思考一点时间。我看一下大家水平。好,大家有打二的,有打三的,好,那那我就放心了,那么你们今天一定要好好听这节课好不好?答应开的老师不要中途离开,一定要好好听这节课。我们首先来直接来运行一下,我们来看一下到底会输出多少,咱们呢,可以清空一下,现在我点击。来,大家告诉我。这个地方正确的应该是多少?正确的是不是是个一吧,然后呢,这里面正确的是多少,是不是应该是一个三。然后呢,在接下来这个正确的是多少,是不是一个四。来,有没有同学回答,对。好像我看到是没有同学回答,对。
04:00
那么这个过程中,那么我们就来看一下,那到底为什么会出现这个问题,怎么来解决这个问题,那么首先第一点我们来看一下,我们要研究明白这个block,那么需要我们去研究哪几个知识。第一种。我们可以看到是不是有一个杠杠strong修饰的和一个杠杠未可修饰的这个block,那么首先第一点,那么这两种类型,这两种修饰,那么代表block是哪几种类型呢?或者说对block有什么影响呢?我们来放到这个地方。有什么影响?那么这个是我们第一个要解决的问题,那么第二个问题是什么呢?第二问题是不是那么这两种类型的block捕获这个变量,捕获这个变量O。那么为什么会产生截然不同的一个效果呢?对不对,所以说哎,我们接下来就来探索一下,哎怎么去解决这个问题,那么首先第一点,我把这个代码来保存到一个。一个方法里面。怎么又又都是垃圾的呢?
05:00
ELC。一个一个。简单写一下,把它放到这里。那么要明白这一点,那么我们首先来看第一个问题,那么我们知道在我们的OC中,Block是不是作为一个对象,那么具体怎么来表现呢?哎,我们可以通过一种方式。哎,来验证一下怎么来验证,那么我们在这个地方有一个N,一个加我们的block的一个分类,那么在这个分类里面呢,我干了一个事情,我重写了,重写了方法,那么接下来我就来干的事情,我来的地方。我干个什么事,我打个断点,打个断点我来到我里面,我接下来ns log。LO100分号我来这里面我打印一个block,那么这个block我就直接这样这样来写。再来写。那么我们来看一下它能不能调到我们的方法,那么如果说它能调到的话,我们就知道是不它的IC指针最后一直指向你,是不是也是我们的NS债啊,那我们直接来运行,直接来运行。
06:06
来,我们看一下是不是在这个地方掉掉的,哎,不是在这个地方,我们把它来放到这里面,放到这里面来跳过。看我点击。点击。一个。看到glass,现在这glass是前面后面加了两个斜杠,我把它放到这个地方,放到这里。我再来跑一下,跑一下。现在是不是进来了,是不是进来了吧?那说明什么?说明我们的block是不是它确实在我们OC中表现为作为一个对象吧,这个地方验证大家能看明白吗?能看明白的同学给我扣个一,是不是确实作为一个对象吧,而且这是一种什么类型的block,是不是global类型的一个block?那么再一个地方,那么我们知道我们OC的对象是底层,它是一个结构体,结构体。结构体。我们知道是不是它底层,如果你了解过wrong time的话,它是不是有一个glass t这么一个结构呀,Glass t这么一个结构,那么也就意味着是不是我们的block,它底层是不也是一个结构体,也是一个这么一个形式来表示呢?
07:12
哎,当然是的,那么实际上block是什么呢?是用自己的一种类型的结构体来模拟了我们OC中的这种类似glasst的这种东西,那么它里面也有IC指针,也有相关的一些啊,我们需要的一些对象,那么怎么来验证这个事情呢?哎,我们知道是不是可以在我们的OC中可以把什么,可以把我们的代码是不是从我们的一个OC的状态,是不是转化成我们C加加一个状态。那么这个转换这个命令大家应该都知道,那么接下来我们就来转换来看一下,诶,转换成C加加之后的一个block到底是什么样的一个状态,那么我们可以看到在这个地方我已经预先写好了。一个block是不像我们刚才写的一样,Aslo in获取它的return count,然后呢,这个地方,那么这个地方没有任何的修饰,我们知道在我们OC中IC下前面没有默认的修饰,是不是它前面默认就是一个杠杠状呢?
08:08
这个没有问题吧,是不是前面就是一个默认的杠杠strong。然后接下来我怎么把它转化成我们的C加加代码呢?那么要找一个入口去执行我们的一个命令。那么大家可以看到在这个地方我了一个CMD的CMD的命令,通过我们的C来进行一个配置,那么这里面我写了三句我们的需要命令。第一句透。Sc root block test,那么也就是什么呢?这句post代码就是进入到我们的慢点M所在的一个目录,然后呢,在这个目录里面执行这个叉c room,杠sdkphone,这个把它转化成C加加的代码,然后最后一句是什么呢?转化成C之后,再把这个open是吧,把它打开,然后呢,最后从我们当前这个目录里面再去。那么这个是我们要执行的命令,接下来怎么来执行呢?我们来到我们的终端,要输入TT,获取当前终端的一个标识图,那么TT,哎,000。
09:08
000,然后呢,把它放到这个地方,放到这个地方之后呢,我直接来运行我的代码加B编译一下。那么这个地方有什么好处呢?我们知道平时我们再去执行,我们再去执行这个脚本的时候,是不是会把什么会把我们执行脚本的信息是不是输入到这个的这个里面,这个里面是不是不是很清晰啊,但是呢。我们这次是不是可以把我们这个编译的信息整个的输出到什么。输出到我们当前的终端吧,是不是这样就会清晰很多,哎,我们再来一遍,再给大家来看一下。我输入TT获取咱们当前终端的一个标识符,那么获取当前终端的标识符之后,我把它放到这个地方,放到这个地方之后我卡的加B再来编一下。
10:00
编一下之后,大家看到没有,现在是一个什么,是一个有八个warning,是不四个错误,也就说明什么,我们是不是并没有转化成功吧,那么并没有转换成功,我们来看一下到底是哪个地方出现了问题,出现了问题我们来到我们当前这个慢点M这里面。看一下到底是哪个地方出现了问题。啊,这个地方我加了这个杠杠strong的这个事儿。我再来他们的家具编一下。然后呢,大家看到没有,是不是现在只有没有错误了,而且我们的慢点CPP文件是不是已经打开了,那么接下来我们的加B来看一下。那么这个函数里面的代码是不是就对应着我们写在这个block text.m里面代码?那么这个代码我们可以看到,我们可以看到什么?然后呢,接下来在这个地方是不是就是我们定义的这个block,然后呢,现在这个block这个地方Y的括号星,这是一个什么。
11:05
这是一个函数。函数。指针吧,这个大家知道吗?是不是这是一个函数指针,那么也就是说这个指针是不是指向了一个函数,那么指向了哪个函数呢?是不是指向了这个取地址符号的这个函数啊,也就是这个杠杠慢BLOCK0,那么这是一个什么函数呢?我们来看一下。是不是这是一个结构体的一个构造函数,那么也就意味什么说block在底层,它确实是一个结构体,而且大家看到没有,是不是它也是有一个ISA指针,并且呢,它这里面有一个function p drr,那么这个PDR是干什么呢?大家看到没有,这里面写的是什么?是一个ns log啊,是不这些什么东西是不是正好对应着我们写在block代码块里面的一个代码?Block代码块里面代码大家看到没有是正好对应的,哎,Get count,那么也就说明什么,我接下来告诉大家就两点,你看完这个代码一定要记住两点,第一点,Block在底层是一个结构体,这个结构体里面有ISA指针,有一个function p DR,这个function p drr指向了你写在block代码块里面的这个。
12:18
代码把它保存了,这个函数明白没有,实际上我们写在block代码块里面,代码是保存在底层的一个函数里面。然后呢,我们的这个结构体里面又保存了这个指针,这个地方大家明白没有明白的同学给我扣个一,一定要明白,不明白我再给大家讲一遍。Sa方程PTR保存了这个函数的指针好不好?好,大家都说明白了,都说明白之后,那么我来给大家诶加深一下印象,那么怎么加深一下印象呢?那么大家看到我这个touch begin,那么在这个touch begin里面呢,我定义了一个block,那么这个block首先第一点它是一个用杠杠修饰的这么一个block。
13:02
那么这个地方就牵扯出来了,哎,为什么我要用杠杠胃可修饰不?那么也就意味着我们普通的这个没有用杠杠位克修饰的和用杠杠位克修饰的,那么它到底有什么区别?那么这个地方我就不卖关子了,我直接给大家来看一下,就是怎样来判断一个block的一个类型,那么在判断之前我先调一下大家的胃口,那么我来到这个地方,我上面是不是定义了一个像我们正常使用的一个copy修饰的work的一个,那我们来到地方。我要付的一个。的一个多。多来回错。那么请问我现在这个self的多是一个什么类型的block?四要素的一个。做了。来是一个什么类型的lo?Global的给我扣个一,JL global的扣个一,然后呢,我们那个mylo的来扣个二,然后呢,我们那个的来扣个三。
14:00
什么类型的不?我看大家诶,还是有很多同学,哎,咱们的VIP同学还是能扣对的,这是什么类型的block,是不是一个个类型的block,我们直接来看到这个地方,我打一个断点,哪个断点来。稍等啊。电机。我们看到这个地方self的一个do work是不是一个global类型的block,那么并不是它为它用copy来修饰,那么就是一个malo类型的block,那么这点大家一定要想清楚,那么从这个问题就来看到,哎,我们怎么来判断block的一个类型呢?那么在这个地方泰老师总结了几点规则,那么首先第一点。刚才那个global类型block,我们来看到global判断第一点,它是位于全局区,也就是位于我们的一个代码区,那么在block内部不使用外部变量,或者只使用静态变量和全局变量,那么是我们global block,那么我们看到这个block。
15:00
首先第一点,它用copy来修饰,它是不是有强引用,但是呢,它内部是不是并没有捕获任何的变量吧。对不对。对的同学,给我扣个一就没有捕获任何的变量吧,那么所以说这是一个格global类型的block,大家一定要记住这一点,没有使用外变量,或者只使用静态变量,是格global类型block,那么我们的堆区和区有什么区别呢?那么首先第一点。堆和栈都能捕获变量。这也就是为什么。为什么我们当我们看到这个问题的时候,我们第一开始,哎,我给大家镇住的这个问题的时候,为什么。这个杠杠里面也能打印出它的,就是因为堆和栈都能补获。我们的变量,但是呢。什么时候是堆?只有当你的这个block捕获了局部变量或者OC属性的时候,并且赋值给清理用,或者拷回来修饰,那么它才是对,那么不复制给清理用,那么它就是占明白没有。堆和站都能捕获变量,但是呢,区别是什么呢?有没有赋值给强引用或者copy来修饰?
16:06
这个地方大家一定要记住啊。一定要记住。记住了没有,一会儿你们没记住,我跟你说我。我要,我要,我要笑话你们了。好,你们都说记住了,那么记住之后,我们反过头来来看这个不老。那么这个block我是不是用杠到位来修饰的,然后呢,我的block内部是不是捕获了我们的局部变量A,那么请问这是一个什么类型的block?这是一个什么类型的block?对战global,快点。你们刚才不都记住了吗?是不是这是一个站上的不老草,为什么?是不是我通过加了一个杠杠胃,没有让它赋值给强引用吧,对吧。好,那么接下来我们接着往下走,那么我们知道block底层它是一个结构体,那么所以在这个代码上面,那么我就把这个block。
17:01
把这个block week,我们的一个block转化成我们底层结构体的这种形式,我在这个地方定义了一个结构体来进行一个接收,那么这个结构体里面也有IA指针,那么这个IA指针大家都知道,那么这个work代表了我们底层保存我们代码块代码的那个函数。函数。那么接下来我们来干一个事情,干一个事情我们接着往下走,那么接下来我现在有一个杠杠strong的一个strong block。来接收了。我们这个block,那么请问。现在这个strong block是一个什么类型的block?葛老宝1MALO2。这我们扣三。什么类型的?大家都是扣三是吧,大家都是啊,还有扣二的是吧。那么这个地方大家有疑问我们先不管,那么接下来那么一点我们来看一下。
18:02
首先我让大家要明白一个道理,我先不给大家演示一个结构,先让大家明白一个道理,那么当我们执行到这句代码的时候,我们说过说log底层它是一个结构体嘛。那么再执行这个代码数,是不是就是一个结构体等于结构体呢?是不是结构体的一个负值,那么结构体的一个负值也就意味着什么?是不是我把我的IC指针赋值给你,那么我们两个人的IC指针是不是一样的?是不是一样的。我把我的函数指针赋值给你,也就是说我们两个人的函数指针是不是也是一样的?好,那么让大家明白这个道理之后,那么我再来问一下大家,这个地方的block应该是一个什么类型的block,我把我的sa复制给你,我本来是一个。是不是你现在这个地方应该也是一个stick吧,对不对,是不是应该也是一个类型的block。
19:02
结构体的赋值是不是结构体的一个赋值好,那么如果这一点大家再不确定的话,那我给大家来验证一下,你验证一点是什么呢?大家看到我这句代码没有。我是不是把这个结构体的block的work复之为new,复值为new之后,那么如果说。你这个strong block跟block。进行了拷贝的话,哎,我们strong block变成了蹲上了block,那么也就意味着他两个人的指针是不是指向两个地方了,对不对,能理解吧,能理解同学给我扣个一。是不是指向了两个地方?那么如也就是什么?也就什么意思呢?如果说指向了同一个地方的话,那么它两个结构体的隐沃克是不是应该是一个?那么也就意味什么呢?如果是一个的话。我在这个地方打一个断点,那么再去执行这个代码的时候,是不就会错,如果是两个的话。那么这个地方是不会报错。
20:02
是不是这样?我来点击,点击之后,首先第一点我们来到这。这是我们的IC矩阵。我点击。点击现在来到这个地方,我们首先看我的一个strong block是不是确实是一个take类型的block,那说明什么?是不是刚才我讲的是对的,是不是这个地方就是一个结构。一个结构复制吧,我把我的sa复制给你对不对,我把我的方程P是不是复制给你,那么接下来我们再为了加深这个印象,我们再来验证一下,验证一下之后呢,我们往后走。现在什么呢?其中的一个结构体的in work是不是已经置为六了?然后呢,我再往后走是不是报错了,那么这个地方报错了,是不是更加验证了我前面的这个想法,是不是确实是一个结构体等于一个结构体的一个负值啊。这点大家听明白没有?听明白的同学给我扣个一,能听明白吗?
21:03
这点非常非常重要,咱们所有的block的一个问题都是因他而起啊,都是因他而起,好吧。好,那么这点大家听明白了,听明白之后,那么我们来做一个题来加深一下印象,加深一下印象,那么在这个下面呢,哎,我给大家准备了一个题。这个地方有一个block,这个block一个方,那么这个首先一我这个地义个杠杠修week block,那么还没有赋值,然后呢,在这个作用域里面,我又定义了一个什么呢?杠杠未可修饰的一个week block,那么请问这是一个什么类型的block?什么类型的?好,有同学说,站站。啊,可以啊,那今天今天没白讲啊,今天大家都可以啊,是不?这是一个take block,是不是一个赞胜的block,为什么?就首先第一点我里面捕获了我们的一个局部变量,是不是只能从我们的堆和战区里面选一个吧,然后呢,我这个block是不是通过杠杠未可来修饰,所以说它没有强移用,所以是一个战胜的非常好啊,今天大家跟着我都把这个类型都判断清楚了啊好,那么接下来我们再来干一个什么事情呢?
22:24
我把这个week block1赋值给这个week block,然后呢,我在这个公寓外面调用这个week block,请问会不会有什么问题?能不能正常的打印这个ns log?能不能正常打印?可以,还有没有同学,咱们123位同学呢。还有没有呢,这位同学不能。给大家五秒钟的一个思考。
23:02
能和不能,我们直接来跑一下,验证一下。放到这个地方,放到这个地方来。你直接来调一下。非要的一个。啊,我们这个,然后就是这个方法来直接来运行我的代码。点击。发现没有没有报错吧,是不是正常打印出来了吧,那么为什么呢?我们来分析一下,首先这点问题的关键是什么呢?问题的关键是出在这个什么,我们这个作用域里面。那么第一点,我们知道站上的一个变量,它有一个什么样的一个特性。有没有同学知道战场的变量有没有什么特性?站上的变量,它是不是由系统自动。这种。回收。处理的,那么他是怎么处理的,是不是当我们调用这个方法的时候,我们当前的系统是不是会针对这个方法在我们的战上开辟一个战争,我给大家来看一下。
24:04
看一下我这个PPT。但在。来,就是这个图。是不是会开辟一个战争,那么这个战争是什么呢?是不是在战上开辟了一块空间,那么在这个战争里面,是不是你创建了一个变量,战胜的变量,包括其他东西是不是都在这个站上面。当这个函数执行完毕,或者这个方法执行完毕之后,是不是这个站的一个空间要被系统给回收啊,就比方说大家看到这个地方是我开辟了这么大一个地址的一个占的空间,那么当这个函数或者方法执行完毕之后,是这个空间要被系统回收啊。那么也就意味着什么呢?我们看到当前这个方法。那么它开辟的占空间是多大?是不是从这个大括号到这个大括号这么大?那么也就意味着我这个战神的变量,它的一个生命周期是有多长,是不是就是有大括号这么长?
25:00
里面的这个临时作用域对它起作用吗?起不起作用。起不起作用。是不是不起啊,对不对,我们来个地方,我们来运行一下,运行一下。来我点击点击之后呢,我来到地方,我执行一个LDB的命令。杠F-MM,就是连源码,包括我们的汇编一起显示。然后来拉过来,拉过来之后我们可以看到这个地方。那么大家看到没有,是不是上面这个地方什么RSP啊,什么RSPRSP,那么是一个什么呢?我们来看一下,哎,简单来看一下,给大家简单来说一下,我来看一下。SP。那么指向我们站的一个底部,那说明什么呢?所以这个地方你虽然不懂,但是你也知道它是不是在开辟一个站的空间,我们知道占的地址是不是由高到低,哎,所以说它要减去一个变量,减去一个变量。才能开辟一个。
26:00
占的地址空间,这点能理解吗?能不能理解就占的地址是由高到低,所以说它要减去一个变量,开辟化空间。那么这是在一开始开辟,那么再在最后结束的时候,那么它有一个专门的地方去回收这个空间。那么所以说这是站跟我们堆的一个明显的一个区别。所以说我们这个BLOCK1,这个在站上的block,那么它实际上它的生命周期是不是有大括号这么长,那也就意味着这个作用率对它根本不起作用。那首先第一点就是它的生命周期正常,第二点我们来看到这个week block等于这个week block1。刚才我说过,是不是这个地方实际上是什么,是不是就是一个结构体。结。构体。等于一个结构体吧,对不对。所以我把我的I sa复制给你,我把我的方程PDR复制给你,然后呢,我是不是还没有出这个大括号,作用域还没有被销毁,所以在一个地方。
27:06
执行会报错吗?是不是不会吧。能不能理解,所以说这个题不会报错,能不能理解?能不能理解,能理解同学给我汇报666。我给大家讲明白了啊,市市面上就没有任何一个博客一个文章能讲这么明白的。我给大家讲明白了啊好。那么这个地方我再给大家再来什么,再来强化一下这个印象,强化一下印象,那么大家可以看到。这个题这个题。那么这个题是不是跟刚才有一点什么不一样?是不?刚才这个地方是用杠杠week修饰的,我现在用了一个杠杠状,那么请问这是一个什么类型的block?什么类型的不牢靠?这是一个lo,没有问题吧,为什么?它里面捕获了我们的局部变量,然后呢,它被强引用了,所以说这是一个堆上的block,是不是我们判断的这个条件捕获了局部变量或者OZ属性,并且复制给强用或者布来修饰。
28:08
那么接下来来到这个地方,我们来看一下。那现在我们的刚刚胃口变成了我们的一个。杠杠状,那么请问还是一样的代码,那么现在再去执行的时候会不会有问题?会不会有问题?来,有问题的同学扣个一,没有问题的同学扣二,给大家五秒钟的一个时间。五。三。二。我把这个代码来拷贝过来之后,我们来直接来执行一下。咨询下。点击之后是不是立马报一个地址访问,为什么?我们来回到刚才这个地方,刚才这个地方,那么我们已知这个变量,我们那个矢状block,它是一个堆上的变量,我们知道堆上的一个作用率有多大。
29:02
是不是它有一个临时作用欲这么大吧,是不是这个大括号内部的这个嵌套的大括号这么大吧,也就是说出了这个作用欲之后,这个堆上的block是不是要被我们block底层的一个函数叫一个下划线。一个。一个release,哎,这么一个函数给进行一个销毁,进行一个销毁,那么怎么销毁的,一会儿我们来看一下源码啊,一会儿给大家来解读一下这个源码。在这个地方会调用block release进行这个销毁,怎么销毁的?从堆上释放这个空间。那么这个地方为什么会崩溃呢?刚才那位同学不是知道了吗?这个地方跟刚才这句代码,跟刚才那个代码有有区别没有。这个代码跟刚才那个代码有没有区别?没有区别吧,就它仍然是一个结构体。结构体。等于这个结构体吧,对不对,是不是仍然是一个结构体等于结构体。
30:03
所以说我现在是不是把我的function p tr复制给了你啊,复制给了这个block吧,对不对。然后呢,出了这个作用率之后,Block release这个函数是不是把我的strong block这个方PDRR释放掉了,那么请问我的block的风P还有没有?还有没有?来有没有。有没有快点儿。是不是没有了,是不是没有了,为什么没有了,是不是因为我的结构体等于你的结构体,我的值是不是就是你的值啊,所以说这个地方它再去调用一个已经释放的一个函数指针。释放。质证。是不是就会报这个坏地址的一个错误啊,对不对。所以这个地方大家明白了没有,大家明白没有,明白的同学给我扣个六六,通过这两个题,你能明白这个堆和占的一个区别,是不是你能明白这个结构和这个结构体等于这个结构吧。
31:11
对不对。如果你再不明白,没有关系,我们接下来还有相关的一个问题,再给大家再来加深这个印象,那么在加深之前呢,然后给大家推荐一下咱们今天这个资料,因为今天给大家准备的这个资料,帮助大家进行一个啊辅助的这个学习。那么大家可以看一下,那今天给大家准备了第一个就是这个编译命令,因为编译命令这一块,刚才我去讲一个啊,咱们这个操作那个命令的时候,没有给大家详细来讲,那么在这里面呢,有详细的一个文档的解释,那么这个文档详细到什么程度呢?你包括像杠I是不是我们的past,还包括杠L指定这个库的路径啊,我在这里面都给大家进行了一个详细的一个说明。包括那个l to是吧,Link time optimization是链接时间的一个优化的参数,我在这里面都有写。
32:00
包括单片和我们的一个呃多呃多片的那种形式,然后呢,包括什么呢?我里面给大家举了一个具体的例子,怎么在叉八六下面进行编译,哎,怎么在我们的一个。编译我们的怎么去编译我们的一个模拟器,怎么去编译我们的iPhone。包括你在编译的时候怎么去链接这个三方库,那么这个地方有助于大家去学习这个马克相关的一些知识。因为大家在学习骂头的时候,一定不要先去看文章,去通过这个命令实际去操作一下,哎,去编译出来,来看一下ma内部到底发生了哪些变化,包括我们的DSY文件是吧?怎样去查看这个DSY文件,怎样去查看里面具体的指定的符号信息。然后怎么去查看我们Mar内部的结构,然后O这当铺啊是这些东西,静态库的压缩解压缩,怎么创建静态库,怎么创建动态库,怎么查看符号表,怎么生成我们DS外文件,怎么移除这个符号表,包括怎么链接动态库,静态库还包括二重排里面用到的一些链接器的参数。
33:03
那么包括我们的内,那么这里面都有一个详细的解释说明,那么这是第一份资料,那么还有一份资料是什么呢?一个可编译的一个OPPOC781的源码,那么这个源码是已经编译好的,大家可以直接拿去运行,那么这个地方主要是我们一会要讲的这个杠杠状和杠杠。Week的时候,那么这个地方要给大家详细来说一下,哎,刚刚week到底为什么会解决这个循环引用,为什么又解决不了这个循环引用,那么这个地方在源码里面是有相关的一些解释的。然后第三个呢,是CH74的源码,那么这个源码是我们马上要讲到的,那么一会儿我会直接用这个源码给大家解释block到底是如何进行拷贝的,同时block又是如何在堆上进行一个释放的。这是给大家提供的这三份资料,这个源码是可运行的,并且我里面都给大家注释好的,那么给大家提供这三份资料,还有需要的同学,那么加一下咱们今天给大家主持的这个小燕子老师来获取一下,今天这个开老师给大家准备这个资料。
34:06
来,小杨老师把自己的微信二维码发一下给大家,放到这个地方。我看一下刚才咱们同学的这个问题,放到这个地方。19啊,没明白给new发消息为什么崩溃,你是给一个已经释放的地址,你去访问一个不存在的地址,是不是它必然会发生崩溃,因为你这个地址不存在嘛,就他就会报这个坏地址访问嘛,对不对?然后呢,十。987。好,加上的同学给我扣个一,我们马上接下来的课程。啊,都加上是吧,加上我就把这个地方关掉,关掉之后我来看一下刚才同学的一个问题。大家对刚才讲的这两个问题有什么疑问吗?如果有疑问,我们先来看一个东西,来看一下。
35:02
我们刚才在这个touch矩阵里面写的这个代码,那么刚才我们说过了,是不是在这个地方,它其实就是一个结构体,等于一个结构体赋值啊。我们刚才是不是通过在这个地方的演示来验证了,他确实是是这样来做的。那么接下来。我们来看一下,我来做一个操作,那么block,它既然它的ISA指针是不是指向我们的is,那么它是不是也能调我们is里面的这个协议里面的copy方法对不对。那么当我这样copy之后,他是不是就满足了?我们那个malo block的这个条件了,对不对,为什么对啊,我们是不是通过拷贝把它拷贝到这个堆上了。所以当我这样再来调用之后,那么这个strong block我再去这样赋值,我再调用,那么这个地方还会发生崩溃吗?大家觉得还会不会?
36:01
是不是不会了,为什么?因为我现在虽然也是一个结构体和一个结构体复制,但是我后面的这个结构体是不是已经是一个拷贝到堆上的结构体了。这不,现在应该有三个结构体吧。哪三个结构体?是不是这个strong block一个结构体,这个拷贝之后的一个结构体。和什么和拷贝之前的这个week block这个结构体吧,对不对,是不是一共有三个这个结构体。那么请问这三个里面哪两个是相等的?哪两个是相等的?给大家五秒的时间思考一下。是不是前面两个是相等的吧,对不对,后面一个是不是已经被拷贝了,那么所以我现在的这个strong block跟这个还是指向一起的吗?
37:03
是不是不是指向一起的了吧,对不对。所以说我现在再去运行还会报错吗?我们来看一下还会报错,哎,我这个地方是不是掉了,这个掉。好,我现在点击。和电机。是不是正常能打印了,哎,我点击点击是不是都能正常打印了,那么这个地方就牵扯一个问题,哎block到底是如何拷贝的,我为什么调用了copy之后,那么就变成了两个结构体,变成两个结构体。那么这位同学说是重新分配的一个地址,那么首先第一点你一定要明白一点啊。我如果说我在底层是不是有这个这么一个函数吧,对不对。这个函数的地址是不是唯一的?他在马克欧的一个地址是不是唯一的,大家觉得是不是唯一的?
38:01
是不是肯定是唯一的吧,为什么?因为我是不是写在这个地方,他参与编译之后,它在哪个地方,是不是它就是在哪个地方吧,对不对。但是呢,我指向这个函数的这个指针。指向它的这个指针。这个指针。是这。那是不是就不是唯一的了,对不对,我这个指针是不可能有无数个指针指向这个函数啊。这个能明白吗?能不能明白,那么当我这个指针置为六之后,我影影不影响底层的这个T函数。不影响吧。我这个指针等于六。会影响你在骂扣的这个地址吗?不影响吧,是不是不影响。能不能理解,不能理解我再讲一遍,能不能理解,能理解的同学给我汇报,666这个地方一定要理解啊。他是在mark。
39:00
O的这个地址是不会变的,但是指向它的这个指针。是不是可以经常变,对不对。能理解了,能理解,所以说这个地方你也能理解了吧,为什么我同样的我相同的东西进行赋值之后,我的方程P是一样的,为什么我是空,它会变,它会崩溃对不对。这个地方应该能理解啊。然后呢,这个地方就有一个问题,一个问题什么呢。哎,就是这个copy,哎copy到底是怎么来的,那么我们接下来看一下这个block的这个源码。啊,不知道大家到底有没有拿到这个源码啊,我们直接来点开这个源码来看一下。那么首先第一点我们来看一下在这个地方。我定义了这个block,这个block是一个什么类型的block?它里面是不是访问了我们OC的这个变量,然后呢。他是不是前面默认是一个杠杠strong,所以这是一个什么类型的。什么类型?
40:00
我马上就要敲出来了啊,我就要敲出来了,我敲了麦了。是不是堆上的block,那么堆上的block也就意味着它要存在一个变化的过程。我们知道微上和。
我来说两句