// 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> 实例方法可以访问类方法(通过类名来访问)
*/
网友评论