美文网首页
第十七章、拓展一之基本问题

第十七章、拓展一之基本问题

作者: Evans_Xiao | 来源:发表于2019-08-09 22:09 被阅读0次

    一、Swift与OC的区别?

    SwiftObjective-C共用一套运行时环境。两者可以互相引用混合编程。其次就是,OC之前积累的很多类库,在Swift中大部分依然可以直接使用。OC出现过的绝大多数概念,比如引用计数、ARC、属性、协议、接口、初始化、扩展类、命名参数、匿名函数等,在Swift中继续有效。Swift大多数概念与OC一样。当然Swift也多出了一些新兴概念,这些在OC中是没有的,比如范型、元组等。

    其实到现在为止Swift离完全替代Objective-C还是很遥远,因为Apple内部一直在用 Objective-C来做一些Framework的开发,底层也不可能用Swift实现,所以现在更多的替代是体现在外部开发。

    优点:
    1、Swift容易阅读,语法和文件结构简易化。
    2、Swift更易于维护,文件分离后结构更清晰。
    3、Swift更加安全,它是类型安全的语言。
    4、Swift代码更少,简洁的语法,可以省去大量冗余代码。
    5、Swift速度更快,运算性能更高。

    缺点:
    1、版本不稳定,之前升级Swift3大动刀
    2、使用人数比例偏低,目前还是OC的天下
    3、社区的开源项目偏少,毕竟OC独大好多年,很多优秀的类库都不支持Swift,不过这种状况正在改变,现在有好多优秀的Swift的开源类库了
    4、公司使用的比例不高,很多公司以稳为主,还是在使用OC开发,很少一些在进行混合开发,更少一些是纯Swift开发
    5、偶尔开发中遇到的一些问题,很难查找到相关资料,这是一个弊端
    6、纯Swift的运行时和OC有本质区别,一些OC中运行时的强大功能,在纯Swift中变无效了
    7、对于不支持Swift的一些第三方类库,如果非得使用,只能混合编程,利用桥接文件实现

    二、OC是动态语言?Swift为静态语言?

    1、动态语言
    是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构。

    主要动态语言:Objective-C、C#、JavaScript、PHP、Python、Erlang

    2、静态语言
    与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java、C、C++

    三、如何理解OC是一门动态语言

    https://blog.csdn.net/wangsongyang617/article/details/79550045

    四、runtime的消息传递机制

    首先,runtime系统会把方法调用转化为消息发送,即objc_msgSend,并且把方法的调用者、方法选择器,当做参数传递过去.
    此时,方法的调用者会通过isa指针来找到其所属的类,然后在cache或者methodLists中查找该方法,找得到就跳到对应的方法去执行。
    如果在类中没有找到该方法,则通过super_class往上一级超类查找(如果一直找到NSObject都没有找到该方法的话,这种情况,我们放到后面消息转发的时候再说)。

    runtime中维护了一个SEL的表,这个表存储SEL不按照类来存储,只要相同的SEL就会被看做一个,并存储到表中。在项目加载时,会将所有方法都加载到这个表中,而动态生成的方法也会被加载到表中。

    简单讲,对象根据方法编号SEL去映射表查找对应的方法实现。

    五、__block和__weak?

    • __block

    对被截获变量进行赋值操作需要添加__block修饰符。__block修饰的变量最终变成了对象。__block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil。另外一点就是__block修饰的变量在block内外都是唯一的,要注意这个特性可能带来的隐患。

    1、__block对象在block中是可以被修改、重新赋值的。
    2、__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

    - (void)test0506_1
    {
        __block NSMutableArray *array;
        void(^Block)(void) = ^{
            array = [NSMutableArray array];
        };
        Block();
    }
    
    • __weak

    本身是可以避免循环引用的问题的。但是其会导致外部对象释放了之后,block内部也访问不到这个对象的问题,我们可以通过在block内部声明一个__strong的变量来指向 weakObj,使外部对象既能在block内部保持住,又能避免循环引用的问题。

    使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil。

    更多详情__block 与 __weak的区别理解

    六、为什么在Block里面不加__block不允许更改变量?

    我们可以发现,系统自动给我们加上的注释,bound by copy,自动变量val虽然被捕获进来了,但是是用 __cself->val来访问的。Block仅仅捕获了val的值,并没有捕获val的内存地址。所以在__main_block_func_0这个函数中即使我们重写这个自动变量val的值,依旧没法去改变Block外面自动变量val的值。

    OC可能是基于这一点,在编译的层面就防止开发者可能犯的错误,因为自动变量没法在Block中改变外部变量的值,所以编译过程中就报编译错误。

    七、为什么自动变量的值没有增加,而其他几个变量的值是增加的?自动变量是什么状态下被block捕获进去的?

    自动变量是以值传递方式传递到Block的构造函数里面去的。Block只捕获Block中会用到的变量。由于只捕获了自动变量的值,并非内存地址,所以Block内部不能改变自动变量的值。Block捕获的外部变量可以改变值的是静态变量,静态全局变量,全局变量。

    1、静态全局变量,全局变量由于作用域的原因,于是可以直接在Block里面被改变。他们也都存储在全局区。
    2、静态变量传递给Block是内存地址值,所以能在Block里面直接改变值。

    八、为什么block能捕获变量

    __block将变量包装成对象,然后在把捕获到的变量封装在block的结构体里面,block内部存储的变量为结构体指针,也就可以通过指针找到内存地址进而修改变量的值。

    九、load和initialize的区别

    load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

    相同点在于:方法只会被调用一次。

    十、关联对象为分类实现的添加对象,对象添加到哪里了?

    关联对象由AssociationsManager管理,并在AssociationsHashMap存储。所有对象的关联内容都在同一个全局容器中。

    十一、了解关联对象的本质

    AssociationsManager
    AssociationsHashMap --> object
    ObjectAssociationMap --> key
    ObjectAssociation --> value、policy
    
    objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key, id _Nullable value, objc_AssociationPolicy policy)
    

    例子说明:

    - (void)setSex:(NSString *)sex
    {
        objc_setAssociatedObject(self, @selector(sex), sex, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    

    self也就是person对象被赋给了AssociationHashMap的key,而@selector(sex)的地址被赋给了ObjectAssociationMapkey,策略OBJC_ASSOCIATION_COPY_NONATOMIC被赋值给了ObjectAssociationpolicy,传递进来的值sex被赋值给了ObjectAssociationvalue

    这种设计的巧妙之处就在于:

    当一个person对象不光有一个属性值要关联时,比如我们要关联heightsex这两个属性时,我们以person对象作为key,然后值是AssociationMap这个字典类型,在这个字典类型中,分别使用@selector(sex)@selector(height)作为key,然后分别利用sex属性的policy和传递进来的valueheight属性的policy和传递进来的value生成ObjectAssociation作为value。而如果有多个person对象需要关联时,我们只需要在AssociationHashMap中创造更多的键值对就可以解决这个问题。

    通过这个过程我们也能明白:
    关联对象的值它不是存储在自己的实例对象的结构中,而是维护了一个全局的结构AssociationManager

    更多请参考Category的本质<三>关联对象

    十二、TCP为什么三次握手、四次释放?

    十三、项目中有没有用到runtime?怎么使用的?

    十四、iOS中成员变量、实例变量、属性区分

    @interface  MyViewController :UIViewController
    {
        UIButton *yourButton;
        int count;
        id data;
    }
    @property(nonatomic, strong) UIButton *myButton;
    @end
    
    • 成员变量

    { }中所声明的变量都为成员变量。yourButton、count、data都是成员变量。
    成员变量用于类内部,无需与外界接触的变量。因为成员变量不会生成set、get方法,所以外界无法与成员变量接触。

    • 实例变量

    实例变量本质上就是成员变量。只是实例是针对类而言,实例是指类的声明。

    • 属性变量

    根据成员变量的私有性,为了方便访问,所以就有了属性变量。属性变量的好处就是允许让其他对象访问到该变量。
    你可以设置只读或者可写等,设置方法也可自定义。所以,属性变量是用于与其他对象交互的变量。myButton是属性变量。

    综上所述可知:
    成员变量是定义在{}号中的变量,如果变量的数据类型是一个类则称这个变量为实例变量。因为实例变量是成员变量的一种特殊情况,所以实例变量也是类内部使用的,无需与外部接触的变量,这个也就是所谓的类私有变量。而属性变量是用于与其他对象交互的变量。

    十五、TCP连接与轮询拉取数据有什么区别?

    十六、自我介绍

    十七、简单介绍一下自己的项目

    十八、iOS开发中的几种设计模式

    目前常用的几种设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂模式、MVVM

    https://www.cnblogs.com/wangbinios/p/7882082.html

    相关文章

      网友评论

          本文标题:第十七章、拓展一之基本问题

          本文链接:https://www.haomeiwen.com/subject/tobkjctx.html