Android 程序员的 iOS 基础入门(二)

1,732 阅读5分钟

1.概述

这一节讲Objective-C语法。

学姐是看的英文书Objective-C Programming:The Big Nerd Ranch Guide,链接为www.bignerdranch.com/we-write/ob…,大家可以去买来看看。

(1)C vs. Objective-C

  • C是面向过程语言

  • Objective-C是面向对象语言,在C语言的基础上补充了面向对象特性

(2).h文件 vs. .m文件

  • .h是头文件,通常在.h头文件中声明实例变量和方法

  • .m文件是实现文件,用来写代码,并实现头文件的方法

2.语法篇

2.1 import

//导入Foundation基础框架
#import 
//导入头文件
#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对应的内存分布情况分别如下图所示:

图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几个实例方法:stringWithFormatlengthisEqualToStringuppercaseString

(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提供的方法:arrayaddObjectinsertObject, 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关键字表示。修饰符默认是atomicreadwrite类型。atomicnonatomic分别是原子和非原子,区别在多线程。读写属性只能是readonlyreadwrite,分别为只读和可读写。

2.6 Inheritance & Class Extensions

- (float)bodyMassIndex
{
    float normalBMI = [super bodyMassIndex];
    return normalBMI * 0.9;
}

图2

  • 通常在.h头文件中声明实例变量和方法,.m文件继承.h文件,并实现其方法

  • 使用super关键字调用父类方法

  • NSObject有一个实例变量:isa指针,,其含义是is-a,每个对象的isa指针指向创建它的对象

  • 发送一个消息给某个对象去查找某个方法时,先根据当前对象的isa指针从当前对象查找,若没有则继续从父类中查找,一直到NSObject对象为止

3.总结

Objective-C语法书看了一半,参考了下大神casatwytxx的建议,决定下两周做一个简单的ToDoList iOS应用程序。

嗯,不出成果,怎么证明自己会iOS呢?说出去别人也不会信,还是拿东西出来说话吧。

欢迎大家关注我的公众号:学姐的IT专栏

学姐的IT专栏

本文原文发自 某学姐, 转载请保留出处, 谢谢.