其实读研之前,我一直都有写东西记录生活的习惯,不过以前可能会有点傻傻的,每隔一段时间写一堆无病生吟的东西发表在QQZone,引来若干好友的称赞,现在想来真是幼稚之极。为什么又开始写这个呢,主要是来记录和分享自己学习iOS的过程和心得吧,开始接触大概有3个月了,刨去中间改论文备考公务员的一个月,实实在在的看书敲代码应该有一个多月吧,看了好多大神的技术博客,也在很多国外的网站上找到了自己所遇到问题的答案,我在学习的时候比较习惯用笔和纸来做记录,于是考虑是不是可以把遇到的问题,学到的新知识,学习的点点滴滴在一个公开的地方记录下来。昨天跑去面试时面试官也建议我要学会分享,算不上分享,更多是自己的记录吧。
第一课我决定把昨天面试问到的一些问题总结一下,基本上之前看书都有看到过,可真正来解释和回答的时候,发现还是很无力。
1.iOS中类别(Category)和扩展(Extension)的区别。
在为系统类作扩展的时候,我们可以不用继承系统类,不需要访问类的代码,在不知道源代码和不能修改的情况下,直接给系统类添加方法。
1) Category的方法不一定非要在@implementation中实现,也可以在其他位置实现,但是当调用Category的方法时,依据继承树没有找到该方法的实现,程序则会崩溃。
2) Category是类的扩展,只能申明方法,不能申明变量。理论上不能添加变量,但是可以使用@dynamic来弥补这种不足。 (即运行时Runtime)
3)类别的方法中,不可以调用super方法。
4)Category方法可能会覆盖同一个class的其它category方法,也可能被覆盖,因为不知道他们加载的先后顺序,出现这种情况在编译的时候就会报错。如果在开发中使用了类别,最好保证类别名不同于使用者的类别名,类别方法名也不同于使用者的类别方法名。
5)下列情况下使用类别:对框架提供的扩展;不想生成新的子类的情况下的扩展;方便做项目管理,可以将一份源码在多个地方共享或者做方法版本管理,多人协作开发,用本地版本替换公共版本的实现。
扩展是一种匿名分类;但是和匿名分类不一样的是,扩展可以添加新的实例变量。一般Extension都是放在.m文件的@implementation的上方,而且必须在@implementation中实现,否则在编译中会报错。
某些情况下,我们需要声明一个@property,它对外是只读的(readonly)而对内是可读写的(readwrite),这时,可以通过Extension实现。
2.__weak和__block的区别
这部分知识在block里有详细讲解,而且很重要,以后会专门用一篇来总结。
3.属性关键字
NSString *pt = [[NSString alloc] initWithString:@"abc"];
上面一段代码会执行以下两个动作
1.在堆上分配一段内存用来存储@"abc" 比如:内存地址为:0X1111 内容为 "abc"
2.在栈上分配一段内存用来存储pt 比如:地址为:0Xaaaa 内容自然为0X1111
assign的情况:NSString *newPt = [pt assign];
此时newPt和pt完全相同 地址都是0Xaaaa 内容为0X1111 即newPt只是pt的别名,对任何一个操作就等于对另一个操作。 因此retainCount不需要增加。
retain的情况:NSString *newPt = [pt retain];
此时newPt的地址不再为0Xaaaa,可能为0Xaabb 但是内容依然为0X1111。 因此newPt 和 pt 都可以管理"abc"所在的内存。因此 retainCount需要增加1
copy的情况:NSString *newPt = [pt copy];
此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@"abc 同时会在栈上为newPt分配空间 比如地址:0Xaacc 内容为0X1122 因此retainCount增加1供newPt来管理0X1122这段内存。
assign:简单赋值,不更改索引计数(Reference Counting)。对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)。
copy:建立一个索引计数为1的对象,然后释放旧对象。对NSString,不能用于NSMutablestring。
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1。释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1。一般是用于字符串(NSString,NSMutableString),数组(NSMutableArray,NSArray),字典对象,视图对象(UIView),控制器对象(UIViewController)等(NSObject及其子类)。
copy与retain的区别:(转)
copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。
retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1也就是说,retain 是指针拷贝,copy 是内容拷贝。
当然在iOS中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying 协议的类可以发送copy消息,遵守NSMutableCopying 协议的类才可以发送mutableCopy消息。假如发送了一个没有遵守上诉两协议而发送 copy或者 mutableCopy,那么就会发生异常。但是默认的iOS类并没有遵守这两个协议。如果想自定义一下copy 那么就必须遵守NSCopying,并且实现 copyWithZone: 方法,如果想自定义一下mutableCopy 那么就必须遵守NSMutableCopying,并且实现 mutableCopyWithZone: 方法。
strong:与retain类似
weak:与unsafe_unretained类似,可以避免野指针。
nonatomic:atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。
3.深拷贝与浅拷贝
找到一篇特别详细的解释,地址如下: