1 变量声明
变量的声明与C语言一样,在变量名前加类型名以下这些数据类型是从C语言中直接拿来使用的:
int n;unsigned int n;char n;unsigned char n;long n;float n;double n;
另外,Objective-C还扩展了一些数据类型,布尔类型用YES和NO来表示逻辑1和逻辑0
BOOL isOK = YES;BOOL isBAD = NO;
Objective-C中的对象声明就是该对象的指针声明
NSString *string;NSArray * array;NSDictionary* dictinary;
2 类的声明和实现的区别
类的声明一般写在.h文件中,而实现则写在.m文件中。.h文件又称为接口文件,它只会规定一个类有哪些成员变量和成员函数,而不去具体实现它。这个.h文件一般由架构师来撰写。.m文件中具体实现类的成员函数,它往往由软件工程师负责。
3 新建对象和释放内存
生成一个对象,有两种方法:alloc+init系列和autorelease释放。
因为没有垃圾回收机制,Objective-C采用计数器的方式来管理内存,使用的时候要特别小心。用retain方法对计数器加1,用release方法对计数器减1
3.1 alloc函数+init系列函数
初始化时,用alloc函数+init系列函数方法时,计数器的状态会被设为1,使用完毕后,务必记得要用release方法来释放内存。
NSArray *array = [[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil];// 对array的一些处理[array release]; // 释放array的内存
用alloc函数+init系列函数的方法生成的对象也可以委托autorelease来释放。
NSArray *array = [[[NSArray alloc] initWithObjects:@"a", @"b", @"c", nil] autorelease];
3.2 autorelease释放
使用autorelease时,初始化对象的计数器值也被设为1。当达到autorelease的scope的时候,该对象就会收到一个release消息,这就实现了内存自动释放。
NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];
3.3 数值
int i = 2int i = 100000000;float radius = 1.0f;double diameter = 2 * M_PI * radius;
3.4 四则运算
num = 1 + 1;num = 1 - 1;num = 1 * 2;num = 1 / 2;
求商的方法是这样的,如果被除数与除数都是整数,则计算结果是向下取整的整数(小数点后面的全部去掉)。
num = 1 / 2; // 0
如果被除数与除数中有一个是小数,则计算结果不舍弃小数部分。
num = 1.0 / 2; // 0.5num = 1 / 2.0; // 0.5num = 1.0 / 2.0; // 0.5
下面是求余:
// 求余mod = 4 % 2;
3.5 自增和自减
// 自增num++;++num;// 自减num--;--num;
同C语言中的自增和自减运算一样,如果单独使用则运算符放在左边和右边都一样,当在代数式和条件式中使用时,则要特别小心。请不清楚的读者网上搜索一下C语言的自增和自减的注意点。
4 字符串
4.1 字符串的表示
字符串使用NSString,用@”"来表示字符串。
NSString是只读的字符串。NSString *string = @"Hello World!";
可修改的字符串要这样声明:
NSMutableString * string = [NSMutableString stringWithString:@"Hello World!"];
4.2 字符串操作
// 与字符串连接NSMutableString * string = [NSMutableString stringWithString:@"aaa"];NSString *joined = [string appendString:@"bbb"];
//字符串追加 NSMutableString *str=[[NSMutableStringalloc] initWithString:@"dd"]; str=[str stringByAppendingString:@"eee" ];
//字符串替换 NSString *str = @"Hello world!"; str =[str stringByReplacingOccurrencesOfString:"world" withString:"China"]; NSlog(@"Your String is = %@",str); 你将会看到输入Hello China
// 与数组连接
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; NSString *joined = [array componentsJoinedByString:@","];
//分割数组
NSString * string = [NSMutableString stringWithString:@"aaa,bbb,ccc"];
NSArray *record = [string componentsSeparatedByString:@","];
// 字符串长度 int length = [@"abcdef" length];
//提取字串
NSString *string = [@"abcd" substringWithRange:NSMakeRange(0, 2)]; // ab
//搜索
NSString *string = @"abcd"; NSRange range = [string rangeOfString:@"cd"];
NSLog(@"%d:%d", range.location, range.length); //如果没有找到,则length = 0
//字符串转换为日期 NSDate *date1=[dateFormatter dateFromString:@"2010-3-3 11:00"];
//日期比较
首先,创建一个日期格式化对象:
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
然后,创建了两个日期对象:
NSDate *date1=[dateFormatter dateFromString:@"2010-3-3 11:00"];
NSDate *date2=[dateFormatter dateFromString:@"2010-3-4 12:00"];
创建日期对象,是通过字符串解析的。
然后取两个日期对象的时间间隔:
NSTimeInterval time=[date2 timeIntervalSinceDate:date1];
这里的NSTimeInterval 并不是对象,是基本型,其实是double类型,是由c定义的:
typedef double NSTimeInterval;
再然后,把间隔的秒数折算成天数和小时数:
int days=((int)time)/(3600*24);
int hours=((int)time)%(3600*24)/3600; NSString *dateContent=[[NSString alloc] initWithFormat:@"%i天%i小时",days,hours];
字符串转换为整数
1 | NSString *aNumberString = @"123" ; |
2 | int i = [aNumberString intValue]; |
dobule di = [aNumberString doubleValue]; //转换为双精度
整数转换为字符串
1 | int aNumber = 123; |
2 | NSString *aString = [ NSString stringWithFormat: @"%d" , aNumber]; |
5 数组
5.1 声明
NSArray *array;
5.2 数组的生成
NSArray *array;array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil];NSMutableArray *array = [NSMutableArray array]; // 声明可修改的数组同时对它赋值
5.3 数组元素的引用和赋值
// 元素的引用[array objectAtIndex:0];[array objectAtIndex:1];// 赋值(NSMutableArray的实例)[array removeObjectAtIndex:1]; // 删除一个元素[array insertObject:@"1" atIndex:1]; // 在删除的地方插入一个元素
5.4 数组的长度
int array_num = [array count];
6 字典
6.1 声明
NSDictionary *dictinary;dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"value1",@"key1",@"value2",@"key2",nil,];NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; // 声明可修改的字典的同时对它赋值
6.2 字典元素的引用和赋值
//元素的引用id val1 = [dictionary objectForKey:@"key1"];id val2 = [dictionary objectForKey:@"key2"];// 赋值(NSMutableDictionary的实例)[dictionary setObject:@"value1" forKey:@"key1"];
6.3 字典的操作
・获得Key
NSArray *keys = [dictionary allkeys]
・获得值
NSArray *values = [dictionary allValues];
・删除Key(NSMutableDictionary的实例)
[dictionary removeObjectForKey:@"key1"];
7 控制语句
if语句
if ( 条件 ) {}
if ~ else语句
if (条件) {} else {}
if ~ else if 语句
if ( 条件 ) {} else if ( 条件 ) {}
while语句
int i = 0;while (i < 5) {// 处理i++;}
for语句
for (int i = 0; i < 5; i++) {//处理}
8 函数定义
虽然大多数情况下是用类中的方法来定义函数,但也可以用C语言的函数定义方法。
另外,还有作为对现有类的扩张的方法,称之为Category。@interface ClassA : NSObject {NSString *name_;}@property (nonatomic, copy) NSString *name_;@implementation ClassA@synthesize name_- (void) helloWorld:(NSString *)name {NSLog(@"hello %@ world! from %@", name, self.name_);}@end
9 文件的输入输出
NSString *inputFilePath = [INPUTFILEPATH stringByExpandingTildeInPath];NSString *outputFilePath = [OUTPUTFILEPATH stringByExpandingTildeInPath];NSFileManager *fm = [NSFileManager defaultManager];if ( ![fm fileExistsAtPath:outputFilePath] ) {[fm createFileAtPath:outputFilePath contents:nil attributes:nil];}NSFileHandle *input = [NSFileHandle fileHandleForReadingAtPath:inputFilePath];NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:outputFilePath];@try {NSData *data;while( (data = [input readDataOfLength:1024]) && 0 < [data length] ){[output writeData: data];}} @finally {[input closeFile];[output closeFile];}
以下语法特性,读者如果知道的话会更好:
高速枚举
使用NSArray或NSDictionar的高速枚举法可以简单地枚举元素
NSArray *array = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];for (id i in array) {//一些处理}
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1",@"value2", @"key2",@"value3", @"key3",nil];// 用key来做循环的场合for (id i in [dictionary keyEnumerator]) {// 一些处理}// 用值来做循环的场合for (id i in [dictionary objectEnumerator]) {// 一些处理}
用临时变量id来做是可以的,不过指明Key的类型这种方法也不错。
for (NSString *k in [dictionary keyEnumerator]) { // 处理}
Category
Category可以在已有的类中追加一个方法@interface NSString (Decorate)// 定义属于Category的方法- (NSString *) decorateWithString:(NSString *)string;@end@implementation NSString (Decorate)- (NSString *) decorateWithString:(NSString *)string {return [NSString stringWithFormat:@"%@%@%@", string, self, string];}@endNSLog(@"test: %@",[@"[MSG]" decorateWithString:@"**"]); // **[MSG]**
Protocol 类如果声明为符合某种Protocol的话,就要按照Protocol所规定的方法来实现这个类。Protocol和Java中的Interface类似。Property Property提供了访问类中成员变量的一种方法。 虽然在使用的时候你应该知道更多关于它的知识,但在这里我们只举一个例子。
@property (nonatomic, retain) NSArray *array_;
如果要对像上面那样声明retain的property赋值的话,如果不通过accessor来访问,那么就无法retain。
- (id)initWithParam:(NSArray *)array {if (self = [super init]) {array_ = array; // 无法retainself.array_ = array; // 可以retain}return self;}- (void)dealloc {[array_ release];[super dealloc];}
由于该状态并不是retain,外部进程可能会对其进行释放,这样就会出现EXC_BAD_ACCESS或者double free的错误发生。
*备注:在java中实现一个接口,那么就必须实现接口的所有方法,但是在OC里就不一定了。
@required 表示必须实现的方法;(虽然说是必须实现,但是编译器并不会强求实现,即编译器不报错,所以也可以不实现。)
@optional 表示可选(可以实现,也可以不实现。)如果不声明任何关键字,则默认是@required@protocol study@required-(void)test;-(void)test1;@optional-(void)test2;@end
block
block的概念:block封装了一段代码,可以在任何时候执行。(外号:代码段)
代码说明如下:int (^Sum) (int,int) = ^(int a, int b){ //^:声明一个block;Sum:声明block名;等号后是实现这个block; return a + b;}int c = Sum(3, 6);//调用block;
typedef方法定义block:
typedef int (^Sum) (int int);//声明一个block变量Sum sum1 = ^(int a, int b);
备注:1.block可以访问外部定义的变量,但是不能修改;
2.如果外部的变量用__block关键字声明,就可以在block内部修改这个变量。