美文网首页
回顾一下OC基础

回顾一下OC基础

作者: 懒惰的习惯 | 来源:发表于2019-03-01 20:02 被阅读0次
    // 1. weak与assign之间的区别
    /* 我的看法:
     * 使用:
     * 1> weak在循环引用中能使一方释放引用,从而解决循环的问题,比如delegate,block内
     * 2> 如果有一方已经强引用一个OC对象,则在另一方引用就不需要强引用,使用weak即可,避免重复引用,比如UI控件
     * 不同:
     * 1> weak其实和assign一样,都只是简单的生成seter、getter方法,而并不会对setter方法进行其他的操作,这是相同点。
          同时,weak在一个运行循环结束后,销毁对象时,会自动将weak对象置nil。
     * 2> weak只能用于OC,assign可以用做Foundation的基本数据类型。
     */
    
    // 2. 怎么使用copy关键字
    /** 我的看法:
     *  使用:
     *  1> 在属性是NSString(NSArray、NSDictionary)时,需要使用copy内存管理。
     *  2> block也基本采用copy,虽然block使用assign创建或strong、weak也行,只是当ta一创建则被ARC放进了堆中(执行了copy
           操作)
     *  为何?
     *  1> 如果使用strong,则会对NSString进行强引用,而不做其他操作,这会导致如果是NSMuttableString,则在本属性不知情的情
           况下,更改了内存中的值,比如增删改。
     *  2> 如果是weak,在没有其他强引用指向时,则创建即销毁。
     *  3> 如果采用copy,则不会造成在属性不知情的情况下,更新其内存中的值,确保值的唯一性。
     */
    
    // 3. 这个写法会出什么问题: @property (copy) NSMutableArray *array;
    /** 我的看法:
     *  1> 使用copy操作后,则将可变copy成一份不可变对象,那么就保证了值了唯一性,不会执行增删改的操作。
     *  2> atomin具有同步锁的功能,但同步锁的效果不好,而且在setter方法中加了一些不必要的代码,造成了性能损失,因此一般采用
           nonatomic,并且同步锁的的功能应该采用其他机制,比如@singnized,NSLock,信号量等
     */
    
    // 4. 如何让自己的类具有copy修饰符?如何重写带copy的关键字setter?
    //   这个太复杂,下一个,可自行google
    
    // 5. @property的本质是什么,ivar、getter、setter是如何添加到类中的?
    /** 我的看法:
     *  property = ivar + setter + getter
     *  ivar + setter + getter 是在编译过程中,编译器自动生成的,并且将ivar添加进了ivarlist中,setter、getter方法添加
        进了methodlist中,property的描述添加进了propertylist方法中,并且添加了对象的偏移量,这个是硬编码,就是property在
        内存中的位置,并以后通过这个偏移量来访问其值。
     */
    
    // 6. @protocol和category中如何试用@property
    /** 我的看法:
     *  1> 在protocol中添加属性,则只会生成ivar以及setter、getter的声明,而在遵循此protocol中实现它们
     *  2> 在category中添加属性,则只会生成ivar,而getter、setter方法需要用运行时objc_getAssio..以及objc_setAssio..
           来实现。
     */
    
    // 7. runtime如何实现weak?
    /** 我的看法:(比较粗略)
     *  将weak对象和指针放入一个weak表中,如果对象的强引用为0,则将此weak移出weak表,并将ta在运行循环结束时销毁
     */
    
    // 8. @property有哪些修饰符?并且有哪些关键字?
    /** 我的看法:
     *  1> 原子性: (atomic默认, nonatomic)
     *  2> 可读可写性: (readwrite默认, readonly)
     *  3> 内存管理: assign、strong、weak、copy、unsafe_unretained
     *  4> setter<name>、getter<name>的方法名更改
     *  5> 修饰符有一些不常用的,比如nonnull、null_resettable、nullable
     */
    
    // 9. weak属性需要dealloc时,置nil吗?
    /** 我的看法:
     *  不需要,在ARC中,无论是strong还是weak对象,iOS都会自动帮我们处理,属性被销毁时,weak也会被自动置nil
     */
    
    // 10. @synthesize和@dynamic分别有什么作用?
    /** 我的看法:
     *  1> @synthesize就是告诉编译器,ivar的实例变量名字,默认是@synthesize var = _var;
     *  2> @dynamic就是告诉编译器,setter、getter方法我自己写,不用你自己生成,如果没写,则编译器没问题,运行时因为你没写而
           造成崩溃
     */
    
    // 11. @property中NSString(NSArray、NSDictionary)中的copy有什么作用?如果改为strong会有什么后果?
    /** 我的看法:
     *  1> 因为NSString(NSArray、NSDictionary)有NSMuttableString(NSMuttableArray、NSMuttableDictionary),使用
           copy为了防止,在自己不知道的情况下更改了属性值。
     *  2> 如果采用strong,则因为父类指针可以指向子类对象,则在子类对象不知道的情况下,通过父类指针给改掉了属性。
     *  3> 在集合类(NSArray、NSSet、NSDictionary)、非集合类对象里(NSString),使用copy、muttableCopy之后是:
           非集合类采用copy后,都是指针拷贝
           非集合类采用muttableCopy后,都是内容拷贝
           集合类采用copy后,是指针拷贝
           集合类采用muttableCopy后,都是内容拷贝(指的是对象是内容拷贝,集合内部的元素仍然是指针拷贝)
     */
    
    // 12. @synthesize的合成实例变量规则是什么?如果存在成员属性foo,并存在一个_foo实例变量,那么还会自动合成新变量吗?
    /** 我的看法:
     *  1> 不会
     *  2> @synthesize的合成规则:
     *     一:同时存在setter、getter方法
     *     二:存在getter方法
     *     三:使用@dynamic
     *     四:使用@protocol重写了所有的属性
     *     五:使用@category重写了所有的属性
     *     六:重载的属性
     *  3> 实例变量 = 属性 = ivar
     *  4> @synthesize: 自动合成setter、getter方法,以及自定义ivar名字,一般建议都使用默认ivar
     */
    
    // 13. 给一个nil对象发送消息,会发生什么?
    /** 我的看法:
     *  1> 给nil发送消息,在oc当中是合法的,并且能通过运行。
     *  2> 给nil发送消息,如果返回值对对象,则返回nil,如果是其他定义类型,则返回0,比如结构体,所有成员值都是0,如果是为定义类型,则返回未定义
     *  3> 因为oc是运行时语言,如果给对象发送消息时,调用的方法实际是objc_MsgSend(id, arg),它并没有返回值,因此给nil发送消息,也就是0地址,则对象返回nil,类型返回0,未
           定义返回未定义
     */
    
    // 14. objc中给一个对象发送消息,和objc_MsgSend()有什么关系?
    /** 我的看法:
     *  1> objc是一个运行时语言,当给一个对象发送消息时,最后都会转化为
           objc_MsgSend()。
     *  2> 也就是说,objc中的对象是oc中的表现形式,而在oc中调用方法,实际
           就是给对象发送消息,这就是运行时的特性。
     */
    
    // 15. 什么时候会报unrecognized selector异常?
    /** 我的看法:
     *  1> objc是一个动态语言,方法的调用,也就是发消息,和类,是在运行时才
           能确定的
     *  2> 当给一个对象发送消息时,大概的调用过程是:
     *       一:转化成objc_MsgSend()方法
     *       二:通过isa找到对象所属的类
     *       三:然后找到实例方法或父类方法运行,找不到就崩溃
     *            但在此之前有几种拯救方法:
     *              一> 动态添加方法调用
     *              二> 将消息转发给其他对象,让它调用方法实现
     *              三> 通过修改或删除函数签名,让消息自己消化
     *              四> 产生unrecognized selector(方法未实现异常)
     *
     */
    
    // 16. 一个objc对象如何进行内存布局?(考虑有父类的情况)
    /** 我的看法:
     *  1> 首先,这个对象所占用的内存中,存放着父类的成员变量以及自己的成员
           变量
     *  2> 然后,每个对象中都存在一个isa指针,这个指针指向它的类对象,而类
           对象中存放着本对象
     
     *  简而言之就是:
     *  一:对象方法列表(对象能接收到消息的列表,保存在它对应的类对象中)
     *  二:成员变量列表
     *  三:属性列表
     *  四:isa指针同上
     */
    
    // 17. 一个objc对象的isa指向什么?有什么作用?
    /** 我的看法:
     *  1> isa指针指向类对象
     *  2> 能够让发送消息得到响应,也就是确定对象的类
     */
    
    // 18. 下面代码输出什么?
    /**
     *       @implementation Son : Father
             - (id)init
             {
                 self = [super init];
                 if (self) {
                    NSLog(@"%@", NSStringFromClass([self class]));
                    NSLog(@"%@", NSStringFromClass([super class]));
                 }
                 return self;
                 }
             @end
     */
    /** 我的看法:
     *  1> self.class super.class 是指对象的类对象
     *  2> 从代码看,这里实例化的只有son,也就是说,在son对象里,存在
           class的实现或重载,即而在调用self.class方法,以及
           super.class时,实际的响应是son,因此都输出son。
     */
    
    /** 标准答案:
     *  1> class的实现只有在NSObject里
     *  2> 也就是不管是self,还是super的实现最终都是NSObject
     *  3> 因此不管是调用self.class,还是super.class,都是NSObject的
           实现
     *  4> 所以查看源代码,class的实现是返回self,也就是实例对象
     *  5> 而此刻存在实例对象的只有son,因而输出son
     *  重点:
     *  1> 在init方法里面最好不要使用self.xxx,也就是 "点" 语法
     *  2> 因为在init里面使用点语法,有可能会调用子类的重载方法(在重载后)
     */
    
    // 19. runtime 是如何 通过@selector 找到 方法的实现?(包括类方法和实                        例方法)?
    /** 我的看法:
     *  1> 不管是类对象还是实例对象,其本质都是对象
     *  2> 也就是在对象里面,存在一个方法列表,把所有的方法名@selector都存在里面
     *  3> 在方法列表里面还存放着方法名、方法实现、以及参数等
     *  4> 所有通过runtime就能在方法列表里面通过方法名,找到方法实现了
     */
    
    // 20. 使用runtime associate关联对象,需要在对象dealloc的时候释放吗?
    /** 我的看法:
     *  1> 无论是ARC,还是MRC,都不需要
     */
    
    /** 标准答案:
     *  1> 对象销毁的时间表:
        1. 调用 -release :引用计数变为零
        * 对象正在被销毁,生命周期即将结束.
        * 不能再有新的 __weak 弱引用, 否则将指向 nil.
        * 调用 [self dealloc]
        2. 子类 调用 -dealloc
        * 继承关系中最底层的子类 在调用 -dealloc
        * 如果是 MRC 代码 则会手动释放实例变量们(iVars)
        * 继承关系中每一层的父类 都在调用 -dealloc
        3. NSObject 调 -dealloc
        * 只做一件事:调用 Objective-C runtime 中的 object_dispose() 方法
        4. 调用 object_dispose()
        * 为 C++ 的实例变量们(iVars)调用 destructors
        * 为 ARC 状态下的 实例变量们(iVars) 调用 -release
        * 解除所有使用 runtime Associate方法关联的对象
        * 解除所有 __weak 引用
        * 调用 free()
     */
    
    // 21. objc中,类方法和实例方法,有什么本质上的区别和联系?
    /** 我的看法:
     *  类方法
     *  1> 类方法只能类对象访问(对象方法通过类名来访问)
     *  2> 类方法是属于类对象的
     *  3> 类方法中self是属于类对象
     *  4> 类方法可以调用其他的类方法
     *  5> 类方法不能访问成员变量
     *  6> 类方法不能直接调用成员方法
     
     *  实例方法:
     *  1> 实例方法只能通过实例方法访问
     *  2> 实例方法是属于对象的
     *  3> 实例方法中self是属于实例对象
     *  4> 实例方法可以访问实例方法
     *  5> 实例方法可以访问成员变量
     *  6> 实例方法可以访问类方法(通过类名来访问)
     */
    

    相关文章

      网友评论

          本文标题:回顾一下OC基础

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