这一节讲 Objective-C 语法。
学姐是看的英文书 Objective-C Programming:The Big Nerd Ranch Guide ,链接为 https://www.bignerdranch.com/we-write/objective-c-programming/ ,大家可以去买来看看。
(1) C vs. Objective-C
C 是面向过程语言
Objective-C 是面向对象语言,在 C 语言的基础上补充了面向对象特性
(2) .h 文件 vs. .m 文件
.h 是头文件,通常在 .h 头文件中声明实例变量和方法
.m 文件是实现文件,用来写代码,并实现头文件的方法
//导入Foundation基础框架 #import <Foundation/Foundation.h> //导入头文件 #import "***.h" Foundation是一个包含基础类的框架,iOS或OSX开发都需要先导入这个框架
<> 和 "" 的区别: <> 告诉编译器 Foundation/Foundation.h 是Apple库中一个预编译的头; "" 告诉编译器在当前工程中查找 ***.h 头文件
#import 和 #include 的区别: #import 更快、效率更高。原因是: #include 编译器会进行一个文件内容的拷贝粘贴; #import 编译器会先检查其他文件是否已经导入或包含了,若已导入则不重复导入。
//获取当前日期 NSDate *now = [NSDate date]; //获取当前时间距离1970年的毫秒数 double seconds = [now timeIntervalSince1970]; //传入1个参数 [now dateByAddingTimeInterval:100000]; //传入多个参数 [cal ordinalityOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:now] //消息嵌套 double seconds = [[NSDate date] timeIntervalSince1970]; //发送消息给nil Dog *fido = nil; Newspaper *daily = [fido goGetTheNewspaper]; 两个概念: 类方法 和 实例方法 。Line1中 date 是类方法,Line2中 timeIntervalSince1970 是实例方法
类方法前修饰符为 + ,实例方法前修饰符为 -
调用某个方法,在iOS中叫发送消息(个人理解)。发送消息时可以传入0-N个参数
关于消息结构:由3个部分组成。receiver(类或类实例),selector(消息,类似于方法),argument(冒号后面的参数)。Line2、Line3和Line4分别展示了参数为0、1、2的情况。
关于消息嵌套:Line5为消息嵌套调用,等价于Line1-2
关于发送消息给nil。如Line6-7,发送消息给nil是合法的,并不会报错。给nil发送消息得到的结果是无意义的,应该被丢弃
关于alloc & init
alloc 是给对象分配内存, init 初始化对象
alloc 是类方法, init 是实例方法
[NSDate date] 等价于 [[NSDate alloc] init]
NSDate *currentTime = [NSDate date]; NSDate *startTime = currentTime; sleep(2); currentTime = [NSDate date]; currentTime = nil; 上面代码片段1和2对应的内存分布情况分别如下图所示:
//创建常量String NSString *lament = @"Why me!?"; //创建含Unicode字符String NSString *slogan = @"I /u2661 New York!"; //动态创建String NSString *dateString = [NSString stringWithFormat:@"The date is %@", now]; //实例方法:获取String长度 - (NSUInteger)length; //实例方法:判断两个字符串内容是否相等 - (BOOL)isEqualToString:(NSString *)other; //实例方法:String字符大写 - (NSString *)uppercaseString; 字符串格式形如 @"..."
NSString中可以包含Unicode字符,不过要在前面加 /u
NSString几个实例方法: stringWithFormat , length , isEqualToString , uppercaseString
//NSArray列表创建 NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTimeInterval:24.0 * 60.0 * 60.0]; NSDate *yesterday = [now dateByAddingTimeInterval:-24.0 * 60.0 * 60.0]; NSArray *dateList = @[now, tomorrow, yesterday]; //列表遍历 NSUInteger dateCount = [dateList count]; for (int i = 0; i < dateCount; i++) { NSDate *d = dateList[i]; } //旧的写法 NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday, nil]; NSDate *d = [dateList objectAtIndex:0]; //可变数组 NSMutableArray *dateList = [NSMutableArray array]; [dateList addObject:now]; [dateList addObject:tommorrow]; [dateList insertObject:yesterday atIndex:0] for (NSDate *d in dateList) { NSLog(@"Here is a date: %@", d); } 数组分为固定数组和可变数组。固定数组格式形如 @[...] ,只能访问不能改变,可变数组可以动态改变数组元素。
NSArray 提供的方法: count , arrayWithObjects , objectAtIndex 。arrayWithObjects必须以nil结束,表明终止。列表遍历可以使用index索引,如 dateList[i]
NSMutableArray 提供的方法: array , addObject , insertObject , removeObjectAtIndex 。列表遍历使用 for
//BNRPerson.h实例变量 @interface BNRPerson : NSObject { float _heightInMeters; int _weightInKilos; } - (float)heightInMeters; - (void)setHeightInMeters:(float)h; - (int)weightInKilos; - (void)setWeightInKilos:(int)w; @end //BNRPerson.m @implementation BNRPerson - (float)heightInMeters { return _heightInMeters; } - (void)setHeightInMeters:(float)h { _heightInMeters = h; } - (int)weightInKilos { return _weightInKilos; } - (void)setWeightInKilos:(int)w { _weightInKilos = w; } //BNRperson.h属性 @interface BNRPerson : NSObject @property (nonatomic) float heightInMeters; @property (nonatomic) int weightInKilos; @end 如上代码片段展示了 实例变量 和 属性 两种表现形式,两者是等价的。
实例变量:在 .h 文件中声明实例变量,以 _ 开头,并声明getter/setter方法,在 .m 文件中实getter/setter方法
属性:在 .h 文件中声明属性,用 @property 关键字表示。修饰符默认是 atomic 和 readwrite 类型。 atomic 和 nonatomic 分别是原子和非原子,区别在多线程。读写属性只能是 readonly 和 readwrite ,分别为只读和可读写。
- (float)bodyMassIndex { float normalBMI = [super bodyMassIndex]; return normalBMI * 0.9; }
通常在 .h 头文件中声明实例变量和方法, .m 文件继承 .h 文件,并实现其方法
使用 super 关键字调用父类方法
NSObject 有一个实例变量:isa指针,,其含义是 is-a ,每个对象的isa指针指向创建它的对象
发送一个消息给某个对象去查找某个方法时,先根据当前对象的isa指针从当前对象查找,若没有则继续从父类中查找,一直到NSObject对象为止
Objective-C 语法书看了一半,参考了下大神 casatwy 和 txx 的建议,决定下两周做一个简单的ToDoList iOS应用程序。
嗯,不出成果,怎么证明自己会iOS呢?说出去别人也不会信,还是拿东西出来说话吧。