在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
*本文为原创, 转载请注明出处 www.cnblogs.com/hucn
学习Objective-C有段时间了, 写些心得和大家分享讨论. 我的"母语"是C++, 所以会通过和C++比较来加深理解. 文章主要介绍Objective-C的基础知识, 适合Objective-C新手, 熟悉Objective-C的朋友可以不看了, 或是帮忙挑挑错~
1. C和Objective-CObjective-C是C的超集, 即支持所有C的特性, 包括符号重定义typedef, 类型转换, 宏. 增加了面向对象, 异常处理, Block, Catgories等功能, 因此熟悉C的朋友学习Objective-C也会很容易.
2. OO特性Objective-C是一门面向对象的语言, 具有纯正的OO的设计思想. 支持单一继承, 数据封装@private和@protected, 支持运行时多态. 和C++相比, Objective-C在语言层面引导我们使用OOP设计. 用@interfaced定义类类型, @protocol定义接口, 将实现继承和接口继承分开, 支持一个实现继承和多个接口继承.
3. 内存管理对与每个C++程序员, 内存管理是让头疼的事情, 因此在STL和Boost中都提供了智能指针帮助内存管理. Java则通过JVM提供内存的检查和自动回收, 我们不需要也不能手动释放内存. Objective-C则做出了折中的方案, 提供三个内存管理方式: 1. 每个Objective-C对象内置引用计数管理, 当引用计数为0时自动释放; 2. 提供以一次函数调用为生存期的系统管理的对象, 在函数中申请, 函数出栈时释放. 和C++中用局部对象的构造和析构控制资源很像. 3. 提供系统管理的内存池NSAutoRealeasePool, 可以通过创建和释放内存池控制内存申请和回收的时机.
4. 动态特性Objective-C是一个动态语言, 具有在三个层次的动态支持. 1 动态类型 dynamic typing id类型是Objective-C提出的类型, 是一个指向Object的指针, 编译器对所有id类型的对象不会进行编译期型别检查, 这些工作可能会延迟到运行时我们自己做, 或者不做. id是强大的工具, 举例来说一个NSArray, 一个Objective-C的顺序容器, 可以用这个特性存储不同型别的对象, 他们的类型都是id. dynamic typing是后面两个动态特性的基础.
2 动态绑定 dynamic binding C++的多态是由虚函数表vptr实现的, 简单说来虚函数表就是一个间接层, 将虚函数的具体实现和对象的类型剥离. 运行时根据虚函数表而不是变量的类型去执行函数, 这其实就是动态绑定的概念. 和C++相比, Objective-C显得更为强大. C++的虚函数表在编译期就固定了, 不能在运行时修改, 但是在Objective-C中, 你可以!因此你可以在运行时替换函数的实现, 补充现有的实现, 甚至创建新的类成员和方法!!!
3 动态加载 dynamic loading 动态加载是同过Bundles实现的, XCode将程序中需要的Code, Nib, picture等资源打包成bundles. 由系统控制资源的加载, 在内存受限的移动设备中, 动态加载是很强大的功能.我们还可以通过NSBundle在运行期控制资源加载.
5. 容器Cocoa提供几种主要的容器: 顺序容器 NSArray 集合容器 NSSet 字符串 NSString Map NSDictionary 每种都提供了同STL一样强大的操作. 另外上面的所有容器都是初始化后不能修改的, 每种有对应的可修改版本, 如NSMutableArray. 可见Cocoa对只读的容器和可写容器进行了不同的优化策略.
6. 库与设计支持1 MVC和UIKit MVC即Model View Control, Model代表数据, View代表显示, Control代表Model和View之间的控制. MVC是一种复合的设计模式, 将数据、显示和逻辑解耦, 为了方便的修改数据而不影响显示部分, 或是修改显示而不需要调整数据. Cocoa的UIKit是iOS的界面设计库, UIKit是按照MVC模式设计的, 它使得iOS的UI开发快捷并灵活. View对应UIVIew, Control对应UIViewController. UIView负责屏幕上一个矩形区域的显示和用户交互, 通过继承UIView可以定制具体的渲染行为和交互行为. UIViewController负责组织一组UIView, 响应Model的变化, 处理设备方向响应, 组织特殊的UIView, 如UITabBarController组织屏幕下方的一组Tab Bar, UINavigationController组织屏幕上方的导航栏.
2 delegation、依赖倒置和target-action mechanism UIKit中到处都是delegation的影子, 每个UIView或是UIViewController或UIApplicationDelegate都处理大量的delegation. 这样带来的好处是我们不用关心应用程序是怎么执行起来的, 只要处理我们感兴趣的delegation就好了. 比如我们想做一个触碰屏幕的相应, 就在UIView的具现化中实现touchBegan:这样一个函数就好了, 或者我们想在某个View出现的时候初始化些东西, 只需在UIView中实现ViewDidLoad就好了. 其他的事情都交给UIKit处理, 这也是为什么main函数如此简单. 这样我们就"被迫"用依赖倒置原则设计程序, 因为抽象的逻辑已经写好了, 我们就根据他们写写细节吧. target-action mechanism是UIKit处理事件Event的方法. 做过UI程序的人都知道, UI最烦的就是处理各种事件了, 事件多起来逻辑可能很复杂. 这个机制尽可能的减少事件的触发和处理的耦合关系. 通过对一个view调用-(void)addTarget:(id)target: (SEL)action: forControlEvents:(UIControlEvents)controlEvents; 函数设定当这个View的某个cotrolEvent发生时调用target的action函数. 本质上还是delegation, 但是这里的方便之处在于可以多次调用函数为一个Event添加多个响应, 也可以通过将target参数设为nil将事件传递到responder chain上. 这样我们可以在运行时设定事件的处理方法, 而不需改变处理方的实现.
3 观察者模式NSNotificationCenter 在Cocoa中提供了观察者模式的支持, 用NSNotificationCenter的全局实例, 可以方便的添加观察者和对观察者发出Notification. 主要的函数有, // 返回一个NSNotificationCenter全局实例, 类似于单件Singleton. + (id)defaultCenter; // 为anObject添加一个观察者observer, observer的aSelector用于接收Notification, Notification的名字是aName. - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject; // 发送所有anObject的以aName为名的Notification - (void)postNotification:(NSString *)aName object:(id)anObject;
7. 安全性C++中对空指针是很危险的, 对空指针进行寻址会抛出异常, 若不进行处理会导致程序崩溃. 因此会提倡RAII. 而Objective-C中对null的寻址可以正常进行, 只是什么都没做. 这样很大程度上减少了这类异常, 增强了程序的健壮性, 但也为调试程序增加了一些困难. 8. 工具XCode集成了很多优秀的编译器, 调试器, 以及分析工具. 这里挑我熟悉的几点说明. XCode有方便的编辑提示, 快速的代码补全. XCode在代码编辑期就对代码进行实时编译并给出提示, 越早的发现错误, 修改的代价就越低. XCode提供可视化界面编辑工具, IB Interface Builder XCode提供强大的Analyze功能, 方便的进行引用计数分析, 指出可能的内存泄漏或是提前释放, 不仅能够找到可能的位置, 还能找到泄漏或释放的原因, 并用可视化界面帮助程序要分析. XCode提供NSZombie和Instruments方便的追宗、分析并解决程序崩溃的难题.
9. 其他特性和C++相比Objective有一些其他特性, 包括支持的和不支持的: 不支持运算符重载 不支持模板 支持Categories 我理解Categories就是开放了类的定义, 可以方便的对已有类进行扩展. 就像C++中namespace是开放的, 可扩展的一样. Block Block就像是C++0x中的lambda表达式功能, 可以定义匿名函数作为简单调用或参数传递. 和lambda不同的是, Block可以操作local变量, 这使得Block的用途更为广泛. |
请发表评论