回顾一下OC基础

// 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、getter的方法名更改
 *  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基础)