美文网首页
常规面试题总结

常规面试题总结

作者: _RG | 来源:发表于2020-02-20 10:50 被阅读0次

    1.如何让一个自定义对象具有copy功能?

    首先让这个类遵循<NSCopying>协议, 重写- (id)copyWithZone:(nullable NSZone *)zon方法

    例如

    @interface TestCopyObj : NSObject <NSCopying>
    @property(nonatomic,copy) NSString *name;
    @property(nonatomic,strong) Person *person;
    @end
    
    @implementation TestCopyObj
    - (id)copyWithZone:(nullable NSZone *)zone {
        NSLog(@"copyWithZonecopyWithZonecopyWithZone");
        TestCopyObj *obj =  [[self class] allocWithZone:zone];
        obj.name = self.name;
        obj.person = self.person;
        return obj;
    }
    
    - (id)copy {
        NSLog(@"copycopycopy");
        return [super copy];
    }
    
    @end
    

    其实这里写也需要注意person这个自定义选项也需要支持copy

    当属性用copy修饰符修饰时,会直接调用- (id)copyWithZone:(nullable NSZone *)zone 方法

    @interface ViewController ()
    @property(nonatomic,copy) TestCopyObj *obj;
    @end
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        TestCopyObj *objt = [TestCopyObj new];
        NSLog(@"objt = %@",objt);
        self.obj = objt;
        NSLog(@"self.obj = %@",self.obj);
    
    @end
    

    打印结果为

     objt = <TestCopyObj: 0x61800003d960>
    copyWithZonecopyWithZonecopyWithZone
     self.obj = <TestCopyObj: 0x60000003ea80>
    

    当直接调用TestCopyObj方法进行copy时,会调用[super copy]然后调用- (id)copyWithZone:(nullable NSZone *)zone进行拷贝

    列如

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
        TestCopyObj *objt = [TestCopyObj new];
        NSLog(@"objt = %@",objt);
       
        TestCopyObj *objt01 = [objt copy];
        NSLog(@"objt01 = %@",objt01);
    @end
    

    打印结果为

     objt = <TestCopyObj: 0x61800003d960>
    copycopycopy
    copyWithZonecopyWithZonecopyWithZone
    objt01 = <TestCopyObj: 0x61800003da60>
    
    

    2.iOS 空指针 野指针 僵尸对象

    空指针:

    1. 没有存储任何内存地址的指针就称为空指针(NULL指针)。

    2.被赋值为nil的指针,在没有被具体初始化之前,为nil。

    野指针:
    1."野指针"不是nil指针,是指向"垃圾"内存(不可用内存)的指针。野指针是非常危险的。

    示例:
    
    Student *stu = [[Student alloc] init];
    
    [stu setAge:10];
    
    [stu release];这里已经释放内存
    
    [stu setAge:10];---》报错
    
    
    如果改动一下代码,就不会报错
    
    Student *stu = [[Student alloc] init];
    
    [stu setAge:10];
    
    [stu release];
    
    stu = nil; 
    
    [stu setAge:10]; //消息是无法发送出去的,不会造成任何的影响,当然也不会报错。
    
    

    僵尸对象
    遇到exc_bad_access这类问题一般都是僵尸对象引起的,可以开启僵尸模式定位,我们并没有保留他,只是在程序运行到该对象的时候会产生问题,没有谁会运用他,只会定位他然后解决掉

    例如,执行一个未被赋值的block时,就会报exc_bad_access

    @property(nonatomic,copy) void(^Test)(void);
    
    不赋值,直接执行
    self.Test();
    
    报错exc_bad_access
    

    使用野指针访问僵尸对象.有的时候会出问题,有的时候不会出问题.
    1.当野指针指向的僵尸对象所占用的空间还没有分配给别人的时候,这个时候其实是可以访问的.

    因为对象的数据还在.

    2.当野指针指向的对象所占用的空间分配给了别人的时候 这个时候访问就会出问题.

    3.所以,你不要通过一个野指针去访问一个僵尸对象.

       3.1.虽然可以通过野指针去访问已经被释放的对象,但是我们不允许这么做.
    

    开启僵尸对象模式,可以查看僵尸对象

    image.png image.png

    2.iOS KVC实现原理

    首先会寻找是够是对应的key的set方法,
    没有则寻找有没有_key的属性,有就直接赋值给属性
    没有就找key同名的属性, 如果都没有就会报错

    相关文章

      网友评论

          本文标题:常规面试题总结

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