这一节讲 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呢?说出去别人也不会信,还是拿东西出来说话吧。