前言
其实早就想在博客上分享和保存自己的学习笔记了,只是一直碍于没有很好的平台,所以平时都是写在本地,得益于最近创建了自己的博客,现在准备在寒假里投注更多的时间去学习 iOS,不会 像在学校里一样,会有一些杂事分心。现在我开始在这里写下自己碰到的一些问题和记录一些重要的知识点,为自己后来回顾时也可以得到帮助。关于 oc 的一些知识和 iOS 的前面的一些基础我就 不在这里详细记录了,等以后碰到问题时再总结。
@property 的使用
关于 property:它是提供成员变量的访问方法的声明,控制成员变量的访问权限,控制多线程时成员变量的访问环境。property 不仅可以在 interface,在协议 protocol 中可以使用。 @property(attribute1,attribute2,…) 是 property 的官方表达式,其中的 attribute 都是属性。下面我对属性列表做一个小的总结。
控制权限
- 可读性,readonly , readwrite 如果一个属性中的属性列表中存在 readwrite,那么这种属性就是属性变量的默认属性,表示可读可写。也就是说如果没有显示说明属性列表中的 readwrite,那么你申请的属性变量就是 readwrite 属性的。可以使用 get 方法和 set 方法。 如果一个属性中的属性列表方法存在 readonly,那么这个属性变量就是只读的,也就是说你只能使用这个变量的 get 方法了。
手动管理内存的关键字
- assign setter 方法直接赋值,不生成内存管理代码。当属性是一个基本数据类型的时候,使用 assign。
- retain 在 setter 和 getter 方法中加入一些内存管理的代码。当属性是一个普通 OC 对象的时候,使用 retain。setter 方法对参数进行 release 旧值,在 retain 新值。
- copy 复制对象,NSString 使用 copy。setter 方法进行 copy 操作,与 retain 处理流程一样,先 release 旧值,再 copy 出新对象。
线程安全
- nonatomic 非原子,不会生成线程安全的代码,速度快,iOS 通常都是这种
- atomic 原子(默认),会生成线程安全的代码,速度慢
ARC
- strong oc 对象一般使用 strong
- weak 代理和控件一般使用 weak 注意:当两个对象中的 成员变量相互引用 非 ARC:当有循环引用的时候,其中一方必须是 assign,另一方是 retain ARC:一方必须使用 weak
强弱引用问题
强变量
通常,所有对象的指针变量都是强变量。也就是说,将对象的引用赋给变量使对象自动保持。然后,旧对象的引用会再赋值前被释放。最终,强变量默认会被初始化为零。无论它是实例变量、局 部变量还是全局变量,这都成立。
弱变量
有时候需要为对象建立两者之间的关系,每个对象需要引用到其他的对象(可能是两个对象或者对象的循环链表)。 例如,iOS 应用程序使用试图对象在屏幕上展现图形。视图会维护一个层次结构。一个视图上可能展现一张图片,在图片视图内可能展现出图片的标题。将图片视图设置为主视图,标题视图设置为子视图。当主视图显示的时候,子视图会自动显示出来。你可以把主视图想象为父视图,标题视图想象为子视图。图片主视图具有子视图。 当使用视图继承结构时,父视图确实持有子视图的引用,但子视图能够知道父视图也是很有帮助的。所有父视图会持有子视图的引用,同时子视图也会持有父视图的引用。这种循环引用会引发一 些问题。例如,当父视图销毁时如何处理?子视图对父视图的引用不再有效。实际上,视图引用到不存在的父视图会引起应用的崩溃。 当两个对象都持有彼此的强引用时,将会产生循环保持。如果对象任然有引用,系统将不能销毁这个对象。如果两个对象都强引用到彼此,这样就不可被销毁。 解决这个问题可以通过创建其他类型的对象变量,并允许使用不同类型的引用。 这种引用被称为弱引用,能够建立在两个对象之间。在这个例子中,弱引用建立在子到父。为什么? 因为考虑到一个拥有其他对象的对象(在这个例子中是父视图)是强引用,其他对象可能是弱引用。 通过父视图持有子视图的强引用,子视图持有父视图的弱引用,这样就没有循环保持。弱变量也不能阻止引用的对象被销毁。 当你声明一个弱变量时,系统会追踪赋值给这个变量的引用。当引用的时候释放时,弱变量会被自动设置为 nil。这也避免了无意间给这个变量发送消息引起的崩溃。因为变量被设置为 nil,给 ni l 对象发送任何消息都不会有反应,从而有效避免了崩溃的发生。
弱变量能过和代理(delegate)很好的协作。创建一个代理的弱变量引用,如果代理对象被销毁,变量就会被清零。 上面的关于强弱引用的问题是我在书上看到的一段解释,我觉得说的很详细,就贴出来了。 关于强弱引用还是有一点要补充的,强引用就是我们平时通常所讲的引用,它的存亡直接影响到它所指的对象的存亡。如果一个对象不存在指向它的强引用,并且此对象不会显示在列表中,那么它 会在内存中被释放。弱引用其他与强引用差不多,只是弱引用不决定对象的存亡。
synthesiz
使用@property 和@synthesiz 可以使编译器为你自动生成 getter 和 setter 方法。
数据封装
从 plist 中读取已经封装好的数据,一般采用的是懒加载法。如:
Objective-c
//1 懒加载
- (NSArray *)appInfos
{
if (_appInfos == nil) {
//1.1 bundle为应用所在的文件夹
NSBundle *bundle = [NSBundle mainBundle];
//1.2 获取plist的路径
NSString *path = [bundle pathForResource:@"app" ofType:@"plist"];
//1.3 加载plist
NSArray *dicArray = [NSArray arrayWithContentsOfFile:path];
NSMutableArray *tmpArray = [NSMutableArray array];
//1.4 字典转换模型
for (NSDictionary *dic in dicArray) {
AppInfo *appInfo = [[AppInfo alloc] init];
appInfo.name = dic[@"name"];
appInfo.icon = dic[@"icon"];
[tmpArray addObject:appInfo];
}
_appInfos = tmpArray;
}
return _appInfos;
}