美文网首页
iOS学习笔记

iOS学习笔记

作者: 阳光下的小泡沫丶 | 来源:发表于2018-05-08 15:33 被阅读0次

    1.在OC中向一个nil对象发送消息会发生什么?
    在Objective-C中向nil对象发送消息不会报错,只是在运行不会有任何作用。objc在向一个对象发送消息的时候,runtime是根据对象isa指针找到该对象所属的类,然后在该类和它的父类的方法列表里找方法运行。如果向一个nil对象发送消息的话,在寻找对象的isa指针的时候就返回0地址,所以不会出现任何错误。所以发送给nil的消息返回0(nil);

    2.如果@property后面关键字不写,默认是什么?
    默认的关键字,OC对象:atomic readwrite strong
    基本数据类型:atomic readwrite assign

    3.UITableView实现了delegate中的heightForRowAtIndexPath:方法后,rowHeight这个属性的设置将无效。

    4.runtime如何实现weak变量自动设置nil
    runtime会有一个全局的hash表,用weak指向的对象的地址作为key存入,当对象的引用计数为0的时候,对象要释放的时候runtime就会以对象的地址为key查找到所有存有这个对象的weak属性设置为nil。

    5.Block分三种(根据isa指针)
    1 _NSConcreteStackBlock 分配在栈上,只用到外部的局部变量、成员属性变量,切没有强指针引用。生命周期由系统管理,一旦返回后就被系统销毁了。
    2 _NSConcreteMallocBlock 有强指针引用或copy修饰的成员属性引用的Block会被复制一份到堆上成为MallocBlock,没有强指针引用即销毁(ARC机制),生命周期由程序员控制。
    3 _NSConcreteGlobalBlock 没有用到外界变量或只用到全局变量、静态变量,生命周期从创建到应用程序结束为止。

    _NSConcreteMallocBlock是持有对象的(Block会对对象进行retain操作)。
    _NSConcreteStackBlock和_NSConcreteGlobalBlock不会持有对象。

    由于_NSConcreteStackBlock所属的变量域一旦结束,那么该Block就会被销毁。在ARC环境下,编译器会自动的判断,把Block自动的从栈copy到堆上。

    • 手动调用copy
    • Block是函数的返回值
    • Block被强引用
    • 调用系统API传入参数中含有usingBlock的方法

    以上4中情况,系统都会默认调用copy方法吧Block复制到堆上。
    但是我们自己写的方法把Block作为参数的时候就需要我们手动copy一份到堆上。
    copy是把Block从栈上拷到堆上,dispose函数是把堆上的函数在废弃的时候销毁。

    ARC环境下,一旦Block赋值就触发copy。copy会让block持有捕捉到的变量(包括自动变量和__block修饰的变量)。
    非ARC下,Block被copy时不会持有__block变量,会持有其他变量。

    typedef void(^blk)(void);
    @interface MyObject : NSObject{
        blk _blk;
    }
    @end
    - (instancetype)init {
        if (self = [super init]) {
            __block id tmp = self;
            _blk = [^{
                NSLog(@"%@",tmp);
            } copy];
        }
        return self;
    }
    

    所以这段代码在非arc下不会造成循环引用。在arc会循环引用。

    typedef void(^blk)(void);
    @interface MyObject : NSObject{
        blk _blk;
    }
    @end
    - (instancetype)init {
        if (self = [super init]) {
            __block id tmp = self;
            _blk = ^{
                NSLog(@"%@",tmp);
                tmp = nil;
            } ;
        }
        return self;
    }
    

    这段代码就能在arc下防止循环引用(必须调用blk一次),不过一般arc下都是用__weak来防止循环引用的。

    1. C语言有5种存储域说明符(存储类型)
    • typedef
    • extern
    • static 静态变量存储在数据区中
    • auto 默认,修饰局部变量,自动变量存储在栈中
    • register 存储在寄存器中而不是内存中,不能使用&一元运算符,因为不在内存中,定义了 register 它意味着变量尽可能存储在寄存器中,这还取决于硬件和实现的限制允不允许

    7.TCP协议三次握手,握手过程中使用tcp的标志(flag)——SYN(synchronize)和ACK(acknowledgement)
    发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再传回一个带ACK标志的数据包,代表"握手"结束。

    8.将写操作放入栅栏快单独执行,读操作并发执行

    _syncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //读取字符串
    - (NSString*)someString {
         __block NSString *localSomeString;
         dispatch_sync(_syncQueue, ^{
            localSomeString = _someString;
        });
         return localSomeString;
    }
    //设置字符串
    - (void)setSomeString:(NSString*)someString {
         dispatch_barrier_async(_syncQueue, ^{
            _someString = someString;
        });
    }
    

    9.iOS中的静态库和动态库
    静态库和动态库是相对于编译期和运行期的。静态库在程序编译时会被链接到目标代码中,程序运行不再需要改静态库;而动态库在程序编译时不会链接到目标代码中,只是在程序运行时才被载入。
    静态库在链接时,会被完整的复制到可执行文件中,每个APP都会拷贝一份静态库,浪费内存。
    动态库只有一份,程序运行时动态地加载到内存中,系统指挥加载一次,多个程序公用一份,节省内存。

    10.+load与+initialize方法
    +load方法是在runtime组件加载的时候调用的,也就是在main方法之前调用。调用顺序是:父类->子类->分类,系统只会调用一次(可以自己手动调用多次),子类没实现的话不会调用父类的+load方法,分类和类的+load都会调用。
    +initialize方法是在向对象发送第一条消息的时候调用的(懒加载),也就是可能永远不调用。调用顺序是:父类->子类,系统可能多次调用,子类没实现会调用父类的initialize方法(+initialize调用是发消息流程),分类的+initialize会覆盖类的+initialize方法。

    11.nil、Nil、NULL和NSNull的区别
    nil、Nil、NULL本质上是(void*)0,即空指针,即作用完全相同。
    NULL是c语言中的空指针,多用于c对象的置空。
    nil是OC中的空指针,用于oc对象的置空。
    Nil也是OC中的空指针,多用于表示Class的空。
    NSNull是oc对象(有内存地址),用于表示一个内容为空的OC对象。

    相关文章

      网友评论

          本文标题:iOS学习笔记

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