什么时候使用copy关键字?
在使用NSString、NSArray、NSDictionary时,经常用copy关键字。原因:这些类有对应的mutable子类,如果不用copy的话,有可能会在其它地方被修改,造成不可预知的后果;
什么时候使用weak关键字,和assign有什么不同?
在防止引用循环时,可以用weak来解决;
和assign的不同:(1)在对象释放掉后,weak的属性是nil,而assign的则是野指针;(2)weak只能用于OC对象,assign可以用于非OC对象;
如果用copy、atomic关键字修饰NSMutableArray,会有什么后果?
用copy,会导致array找不到对应的方法而崩溃;用atomic,可能会影响性能;
如何让自己的类用copy修饰符?
声明并实现NSCoping协议;
@protocol和category中如何使用@property;
@protocol中很少使用property,如果用到property,只会生成getter/setter,一般是想让实现这个protocol的object实现该property;
category中添加了property也只会生成getter/setter,无法添加实例变量;但可以通过objc_setAssociatedObject方法来实现;
@property后面可以有哪些修饰符?默认有哪些修饰符?
可以有的修饰符有几类:(1)读写权限相关的,比如readonly、readwrite等;(2)原子性相关的,atomic/nonatomic;(3)内存相关的,strong/weak/retain/assign/copy等;
默认的修饰符有:(对于object)strong或(对于基本数据类型)assign,和atomic,不过为了代码可读性,我一般都写上;
@synthesize和@dynamic有什么用?
@synthesize:如果没实现setter/getter,这个关键字会让编译器加上这2个方法;不过现在已经不需要了,因为只要写上@property就会“自动合成”;
@dynamic:告诉编译器,属性的setter/getter由用户自己生成,不需要自动实现;即动态绑定;
copy和mutableCopy的区别?
对于NSArray来讲,copy是指针复制,mutableCopy是(单层)内容复制;
对于NSMutableArray来讲,copy和mutableCopy都是内容复制;
objc中向一个nil对象发送消息将会发生什么?
不会有任何操作,也不会崩溃;从runtime来讲,会先检查这个对象是不是nil,如果是nil的话,就直接结束,不再进行其它操作了;返回值是nil(如果是object)或者0(基本数据类型);
objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
是同一个操作;因为发送消息在编译的时候,就是编译成了objc_msgSend()函数;
什么时候会报unrecognized selector的异常?
如果向一个object发送了它没有的方法,而且对于后续不进行补救的话(method resolution/fast forwarding/normal forwarding),则会报这个错误;
下面的代码输出什么?
@implementation Son : Father
- (id)init
{
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
都是输出sin;原因:调用super方法其实还是先向Son方法发送,只是会用到objc_msgSendSuper();结果还是Son这个类先接收到消息,会先找本类中有没有这个方法,并返回;
objc_msgForward方法是干什么的?
用来做消息转发的;jsPatch用它来实现热更新;
autorelease对象在什么时候释放?
如果手动指定autoreleasepool,则在当前作用域结束时释放;
如果没有手动指定,则由系统自动去释放;更详细地,在runloop开始一次循环时创建pool,在当前runloop迭代结束时释放;
在block内如何修改block外部的变量?
block中不允许修改外部变量的值,因为作用域发生了变化;
加上__block关键字;__block关键字的作用:如果此变量被block持有,就将变量的值拷贝到堆中,并指向堆中,即改变了变量的作用域,使得在block内也可以操作变量了;
如何调试BAD_ACCESS错误?
打开enable zombie objects;或者用Address Sanitizer;