美文网首页
iOS知识点-P2

iOS知识点-P2

作者: nande_糊涂 | 来源:发表于2022-07-12 18:47 被阅读0次

    定风波 · 苏轼
    莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。
    料峭春风吹酒醒,微冷,山头斜照却相迎。回首向来萧瑟处,归去,也无风雨也无晴。

    1、浅拷贝和深拷贝的区别?

    浅拷贝:只复制指向对象的指针,而不复制引用对象本身。
    深拷贝:复制引用对象本身。内存中存在了两份独立对象本身,当修改A时,A_copy不变。
    

    2、系统对象的 copy 与 mutableCopy 方法

    不管是集合类对象(NSArray、NSDictionary、NSSet ... 之类的对象),还是非集合类对象(NSString, NSNumber ... 之类的对象),接收到copy和mutableCopy消息时,都遵循以下准则:
    1. copy 返回的是不可变对象(immutableObject);如果用copy返回值调用mutable对象的方法就会crash。
    2. mutableCopy 返回的是可变对象(mutableObject)。
    
    一、非集合类对象的copy与mutableCopy
      在非集合类对象中,对不可变对象进行copy操作,是指针复制,mutableCopy操作是内容复制;
      对可变对象进行copy和mutableCopy都是内容复制。用代码简单表示如下:
        NSString *str = @"hello word!";
        NSString *strCopy = [str copy] // 指针复制,strCopy与str的地址一样
        NSMutableString *strMCopy = [str mutableCopy] // 内容复制,strMCopy与str的地址不一样
    
        NSMutableString *mutableStr = [NSMutableString stringWithString: @"hello word!"];
        NSString *strCopy = [mutableStr copy] // 内容复制
        NSMutableString *strMCopy = [mutableStr mutableCopy] // 内容复制
    
    二、集合类对象的copy与mutableCopy (同上)
      在集合类对象中,对不可变对象进行copy操作,是指针复制,mutableCopy操作是内容复制;
      对可变对象进行copy和mutableCopy都是内容复制。但是:集合对象的内容复制仅限于对象本身,对集合内的对象元素仍然是指针复制。(即单层内容复制)
        NSArray *arr = @[@[@"a", @"b"], @[@"c", @"d"];
        NSArray *copyArr = [arr copy]; // 指针复制
        NSMutableArray *mCopyArr = [arr mutableCopy]; //单层内容复制
       
        NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
        NSArray *copyArr = [mutableArr copy]; // 单层内容复制
        NSMutableArray *mCopyArr = [mutableArr mutableCopy]; // 单层内容复制
        
    【总结一句话】:
        只有对不可变对象进行copy操作是指针复制(浅复制),其它情况都是内容复制(深复制)!
    三、这个写法会出什么问题:@property (nonatomic, copy) NSMutableArray *arr;
        问题:添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃。
        //如:-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x7fcd1bc30460
        // copy后返回的是不可变对象(即 arr 是 NSArray 类型,NSArray 类型对象不能调用 NSMutableArray 类型对象的      方法)
        原因:是因为 copy 就是复制一个不可变 NSArray 的对象,不能对 NSArray 对象进行添加/修改。
    

    3、如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?

    若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopying 与 NSMutableCopying 协议。
    具体步骤:
        1. 需声明该类遵从 NSCopying 协议
        2. 实现 NSCopying 协议的方法。
            // 该协议只有一个方法: 
            - (id)copyWithZone:(NSZone *)zone;
            // 注意:使用 copy 修饰符,调用的是copy方法,其实真正需要实现的是 “copyWithZone” 方法。
    

    5、写一个 setter 方法用于完成 @property (nonatomic, retain) NSString *name,写一个 setter 方法用于完成 @property (nonatomic, copy) NSString *name

    // retain
    - (void)setName:(NSString *)str {
      [str retain];
      [_name release];
      _name = str;
    }
    // copy
    - (void)setName:(NSString *)str {
      id t = [str copy];
      [_name release];
      _name = t;
    }
    

    6、@synthesize 和 @dynamic 分别有什么作用?

    @property有两个对应的词,一个是@synthesize(合成实例变量),一个是@dynamic。
    如果@synthesize和@dynamic都没有写,那么默认的就是 @synthesize var = _var;
    // 在类的实现代码里通过 @synthesize 语法可以来指定实例变量的名字。(@synthesize var = _newVar;)
    1. @synthesize 的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
    2. @dynamic 告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成(如,@dynamic var)。
    

    7、常见的 Objective-C 的数据类型有那些,和C的基本数据类型有什么区别?如:NSInteger和int

    Objective-C的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是long。
    

    8、id 声明的对象有什么特性?

    id 声明的对象具有运行时的特性,即可以指向任意类型的Objcetive-C的对象。
    

    9、Objective-C 如何对内存管理的?

    Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
    1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。
    2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。
    3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。
    

    10、Objective-C 中创建线程的方法是什么?

    线程创建有三种方法:
    1.使用NSThread创建
    2.使用GCD的dispatch
    3.使用子类化的NSOperation,然后将其加入NSOperationQueue;
    

    11、如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么?

    在主线程执行代码,方法是performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject:waitUntilDone:
    

    相关文章

      网友评论

          本文标题:iOS知识点-P2

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