前言

从上个礼拜五购得这本OBjective-C 编程 (第2版) The Big Nerd Ranch Guide入门级书籍,自己凭着之前学习过的C/C++编程语言经验,一个礼拜时间自学完OC编程基础,写一些自己遇到的难点和解决方法,供日后参考。

属性

属性的不同特征可以用来控制如何创建存取方法,每个程序必用,需要花点时间深刻理解。

@property (参数1,参数2) 类型 名字;
参数可选择
读写属性: (readwrite/readonly)
setter语意:(assign/retain/copy)
原子性: (atomicity/nonatomic)
各参数意义如下:
readwrite:同时产生setter\getter方法
readonly:只产生简单的getter,没有setter。
assign:默认类型,setter方法直接赋值,而不进行retain操作
retain:setter方法对参数进行release旧值,再retain新值。
copy:setter方法进行Copy操作,与retain一样。
atomic:原子性,它没有一个如果你没有对原子性进行一个声明(atomic or nonatomic),那么系统会默认你选择的是atomic。
原子性就是说一个操作不可以被中途cpu暂停然后调度, 即不能被中断, 要不就执行完, 要不就不执行. 如果一个操作是原子性的,那么在多线程环境下, 就不会出现变量被修改等奇怪的问题。原子操作就是不可再分的操作,在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头。当然,原子性的变量在执行效率上要低些。
在其他的一下资料中找到关于异步与同步区别:并非同步就是不好,我们通常需要同时进行多个操作,这时使用异步,而对于程序来说,一般就是使用多线程,然而我们很多时候需要在多个线程间访问共享的数据,这个时候又需要同步来保证数据的准确性或访问的先后次序。当有多个线程需要访问到同一个数据时,OC中,我们可以使用@synchronized(变量)来对该变量进行加锁(加锁的目的常常是为了同步或保证原子操作)。
nonatomic:非原子性,是直接从内存中取数值,因为它是从内存中取得数据,它并没有一个加锁的保护来用于cpu中的寄存器计算Value,它只是单纯的从内存地址中,当前的内存存储的数据结果来进行使用。在多线环境下可提高性能,但无法保证数据同步。

对象

类、对象、实例、方法、类方法、消息等概念梳理。

1.#import 和#include的区别。类的实现文件均在头部引入类的接口文件,#import<Foundation/Foundation.h>,不同于之前的C文件的#include,#import指令导入效率更高,编译器会先检查是否已经导入该文件,或已包含到目标文件,若不存在再执行导入。此外#import会确保预处理器只导入特定的文件一次。
#include指令则告诉编译器做复制粘贴,将包含的内容复制到目标文件夹中,并且允许多次导入同一个文件。
相比之下,#import更快更具有效率。
导入文件时,需为文件名加上双引号或尖括号。若是双引号,编译器会现在项目的目录中查找相应的文件。尖括号,那么编译器会在预先设定好的目录中查找相应的文件。
2.方法与消息。消息是OC内对象或方法执行指令的方式,接收方为指针,只想接收消息的对象的地址,选择器为方法名,要触发的方法的名字。
[接收方 选择器:参数为实参]
3.类方法和实例方法。
实例方法为(-)带头的方法,它属于类的某一个或某几个实例对象,即类对象必须实例化后才可以使用的方法。实例方法会提供实例中实例变量的信息,或者是对实例的实例变量进行操作。
类方法为(+)带头的方法,它是属于类本身的方法,不属于类的某一个实例对象,所以不需要实例化类,用类名即可使用,是将消息发送给类,通常来说,类方法会创建类的实例,并初始化实例变量。

类扩展

类扩展class extension,仅只在类实现文件内implementation.h调用,即为私有成员变量private。这个和书本内说法略有出入,使得我在这个地方徘徊很久,在此感谢下我的好朋友程序猿俊俊对我的帮助,他一句话就点通了类扩展含义。使用class extension 可以非常方便定义和调用私有成员变量。
类的扩展是添加在类的实现文件中,实现方法的@implementation之上的。

避免内存泄露

新手上路,对于内存泄露关注很少,练习中对于强弱引用也没有特别关注到,所以这里对于定义梳理一遍,加深印象。

强引用,strong指针,指针变量指向一个对象,并且是该对象的拥有者。当对象获得新值,或者不再存在时(如局部变量方法返回时、实例变量对象释放时),原对象不存在任何拥有者时,retain计数降为0,这时对象会被释放。strong指针能够保持对象的生命。默认所有实例变量和局部变量都是Strong指针。

弱引用,weak指针,指针变量仍然可以指向一个对象,但不属于对象的拥有者,当对象更改,原对象就会失去拥有者,会自动释放,weak指针将设置为nil。因此标示为弱引用的实例变量与属性指向的对象可能会消失。
weak指针主要用于“父-子”关系,父亲拥有一个儿子的strong指针,因此父亲是儿子的所有者;但为了阻止所有权循环,儿子需要使用weak指针指向父亲。典型例子是delegate模式,你的ViewController通过strong指针(self.view)拥有一个UITableView, UITableView的dataSource和delegate都是weak指针,指向你的ViewController。

第一个IOS程序

开始试验第一个ios程序了!

书本介绍将对View内容添加代码均在app delegate.m文件的application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中,运行提示出错,’Application windows are expected to have a root view controller at the end of application launch’,提示rootViewController未设置。这个问题我在Google上找了一个晚上,各种实验仍未成功,之后在https://forums.bignerdranch论坛上找到了解决方案,在本书中遇到的问题,在该论坛上均可以找到相关解答。在启动方法中添加rootViewController判断,`if(self.window.rootViewController == nil)
{
UIViewController *vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
self.window.rootViewController = vc;
}
指定rootViewController错误即可修复。
MVC模式,model-view-controller,开发程序时所创建的类,均应归结到模型、视图、控制器三种类型。书本中给出的例子并没有严格按照MVC模式设计,这部分内容还需要从IOS编程内继续学习。期间将例子修改成MVC模式,仅供参考。View:新建MyView类,将控件新建在MyView中;model:函数申明;controller:addTask方法实现。

KVC&KVO

KVO(Key-value coding),让程序通过名称直接存取属性,继承自NSObject的类都具备KVC功能。
整本书下来,KVO&KVC应用例子较少,先记下定义。

方法setValue:forKey:,存方法,对象会自动查找set方法,若对象无set方法,则直接为实例变量赋值;方法valueForKey:,取方法,对象会自动查找get方法,若无get方法,就会直接返回相应的实例变量。key,对应起实例变量的名称、属性的名称、或者方法的名称。
KVC只对对象有效,对于非对象类型的属性则可以采用类方法赋值,比方说给int,float,setValue:[NSNumber numberWithInt:20] forked:@”属性”。
KVO(key-value observing),指定的对象的属性被修改的时候,允许对象接收通知的机制。后续cocoa binding 和core data,KVO是重要组成部分。

总结

总体来说,有C基础的基本可以在一个礼拜内兼职学习OBjective-C 编程基础知识。我用的参考书是“OBjective-C 编程 (第2版) The Big Nerd Ranch Guide”,各大论坛均非常推荐的入门级书本,每个例子和练习均敲到Xcode 里运行,能对各个知识点有个更深刻的理解,遇到问题,可以配合书本推荐的https://forums.bignerdranch论坛,里面均可以找到解决方案。
最头痛的莫过于自己的英文能力,学习中在论坛内交流均是采用英文交流,包括提问题、解答。对于我这类义务制教育出来的英文水平,应试可以,但是交流障碍很大,中式英文敲到论坛里面去真是不堪入目。此外apple官方文档也是清一色英文文档,对于英文阅读及交流的障碍亟待克服,日后每天要保证一定的外文阅读量。
今后的计划是在两个礼拜内,学习完《精通IOS开发第六版》,书本已经在家积灰多日了。对于兼职学习来说,精细的计划尤其重要,毕竟每天的学习时间有限。有一起学习的或者将要学习的可以参考下这个方法,个人来说很受用。
若有不足,请大家多多指正。

更多推荐

初学OBjective-C 编程心得