1.概述
这一节讲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
文件是实现文件,用来写代码,并实现头文件的方法
2.语法篇
2.1 import
//导入Foundation基础框架
#import <Foundation/Foundation.h>
//导入头文件
#import "***.h"
这里涉及几个知识点:
-
Foundation是一个包含基础类的框架,iOS或OSX开发都需要先导入这个框架
-
<>
和""
的区别:<>
告诉编译器Foundation/Foundation.h
是Apple库中一个预编译的头;""
告诉编译器在当前工程中查找***.h
头文件 -
#import
和#include
的区别:#import
更快、效率更高。原因是:#include
编译器会进行一个文件内容的拷贝粘贴;#import
编译器会先检查其他文件是否已经导入或包含了,若已导入则不重复导入。
2.2 Method & Message
//获取当前日期
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]
2.3 Object and Memory/Memory Leaks
NSDate *currentTime = [NSDate date];
NSDate *startTime = currentTime;
sleep(2);
currentTime = [NSDate date];
currentTime = nil;
上面代码片段1和2对应的内存分布情况分别如下图所示:
2.4 String & Array
(1)NSString
//创建常量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
(2)NSArray
//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
2.5 Instance Variables & Properties
//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
,分别为只读和可读写。
2.6 Inheritance & Class Extensions
- (float)bodyMassIndex
{
float normalBMI = [super bodyMassIndex];
return normalBMI * 0.9;
}
-
通常在
.h
头文件中声明实例变量和方法,.m
文件继承.h
文件,并实现其方法 -
使用
super
关键字调用父类方法 -
NSObject
有一个实例变量:isa指针,,其含义是is-a
,每个对象的isa指针指向创建它的对象 -
发送一个消息给某个对象去查找某个方法时,先根据当前对象的isa指针从当前对象查找,若没有则继续从父类中查找,一直到NSObject对象为止
3.总结
Objective-C
语法书看了一半,参考了下大神casatwy
和txx
的建议,决定下两周做一个简单的ToDoList iOS应用程序。
嗯,不出成果,怎么证明自己会iOS呢?说出去别人也不会信,还是拿东西出来说话吧。