一直特别想总结一下iOS开发,无奈工作繁忙(当然,主要还是太懒)而拖拖拖,就像减肥一样,明日复明日。好在减肥已于上周开始了,开发总结的话,不如就现在开始吧。
抛开OC基础不说,iOS开发最应该了解的应该就是以下几点了:
- 内存管理
- Category
- KVC & KVO
- Block
- Runtime
- Runloop
内存管理
现在很多年轻的开发者肯定没有经历过MRC时代,肯定会问:内存还需要管理?怎么管理?不是系统帮我们管理么?不理解内存管理,就会导致很多问题,比如无法理解循环引用,无法准确定位某些疑难杂症,无法写出优秀的代码。
首先,什么是内存管理,为什么需要内存管理?内存由操作系统掌握,我们使用一小块内存的时候,是需要向系统申请的。比如告诉系统我要占用1K内存,系统同意之后,就会分配给你1K的内存供你使用。在你使用这1K期间,别的进程或者应用是不能使用的,至于系统何时回收这1K内存,再次分配给别的应用或者进程呢?这就涉及到内存管理了。
既然我使用这1K内存的时候,别的应用或者进程不能使用,那我用完了他们就能用了吧!当然,可是操作系统怎么知道你不再使用这1K内存了呢?引用计数就是一种简单而有效的方法。
当我们创建一个新对象的时候,它的引用计数为 1,当有一个新的指针指向这个对象时,我们将其引用计数加 1,当某个指针不再指向这个对象是,我们将其引用计数减 1,当对象的引用计数变为 0 时,说明这个对象不再被任何指针指向了,这个时候我们就可以将对象销毁,回收内存。 唐巧-理解 iOS 的内存管理
后来,在苹果公司的努力下,ARC出现,我们不用再过度关心在哪retain和在哪release,不用再关心 “谁申请谁释放”,因为ARC模式下,编译器会自动帮我们做这些工作,iOS开发也因此降低了门槛。即便如此,仍然有些地方需要注意内存管理,比如block和代理就经常引起循环引用问题,还有一些偏向底层的库比如绘图等API也需要手动释放内存。
Category
对于iOS框架提供的类,比如NSString,如果我们想加入我们自己的方法myStringMethod,怎么实现?可以写个子类,可是如果我想NSMutableString也想加入myStringMethod呢?总不能给NSMutableString也写个子类吧,分类(Category)就可以实现这些要求。
分类就是对一个类的功能进行扩展,让这个类能够适应不不同情况的需求。在一般的实际开发中,我们都会对系统的一些常用类进行扩展,比如NSString,Button等等,简单来说类别是一种为现有的类添加新方法的方式。
我们可以用Category实现:
- 扩展已有类的方法(包括Apple的SDK)
- 将类的实现分散到多个不同的文件或者不同的框架中,方便代码的管理
- 模拟多继承(另外可以模拟多继承的还有protocol)
但是我们也需要注意:
- Category只能给某个已有的类扩充方法,不能扩充成员变量
- Category可以添加属性,但是@property只会生成setter和getter的声明,不会生成setter和getter的实现以及成员变量
- Category中的方法会覆盖掉类中原有的方法,所以需要避免与原类的方法重名
- 如果多个category中存在同名的方法,运行时到底调用哪个方法由编译器决定,最后一个参与编译的方法会被调用
- 可以运用Runtime来动态添加属性
KVC和KVO
Key-Value Coding 和 Key-Value Observing 是两个非常实用的东西,这里有一篇文章写得挺好:KVC和KVO深入
这里简单说一下:KVC可以绕过setter和getter来访问对象的属性,比如:[site setValue:@"userName" forKey:@"name"];
,开发当中字典转模型就可以用KVC来实现,可以看字典转模型的介绍。
至于KVO,官方解释:
Key-value observing 提供了一种监听某个对象的属性变化的机制,当被监听的对象的属性发生变化的时候,监听者就能被通知到。KVO通常用于model和controller layers之间的通信。
KVO的实现原理也在官方文档中提到了:KVO实现原理
KVO用到了 isa-swizzling 方法大致上就是当你对A对象注册监听的时候,isa指针指向了A对象的一个子类(系统默默生成的),当调用setter方法的时候,调用的自然也不是原A对象的方法,而是子类的setter方法,子类的setter方法中在属性变化前和后分别会发出两个通知,去通知监听者属性发生了变化。文档最后提到:
You should never rely on the
isa
pointer to determine class membership. Instead, you should use the class method to determine the class of an object instance.
也就是说,isa并不能确定一个类,只能用class
方法来确定。
Block
关于Block,官方文档Working with Blocks是这样描述的:
An Objective-C class defines an object that combines data with related behavior. Sometimes, it makes sense just to represent a single task or unit of behavior, rather than a collection of methods.
Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary.They also have the ability to capture values from the enclosing scope, making them similar to closures or lambdas in other programming languages.
其中 Blocks are Objective-C objects 说明了 Block的本质,至于Block的用法,这里写的很详细 Blocks Programming Topics 所以就不赘述。
Runtime
官方文档同样有介绍:Objective-C Runtime Programming Guide
The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.
文档中指出:OC尽可能多的将决定(这里应该是决定对象的类型)由编译时、链接时推迟到了运行时,尽量做到动态,所以会说OC是动态语言。
网友评论