暂时忽略这个,因为我觉得在C++中,多重继承都不是太常用P124
在可能会抛出异常的代码块用@try标记
@catch指令标记的代码块,用于捕捉@try语句块中的抛出的错误
@finally语句块中包含的代码是不论程序是否抛出异常都会执行的代码
可以使用@throw自己抛出一个错误,这个错误一般熟NSException类的对象
试个例子P130
// // main.m // test // // Created by Zeng on 13-5-24. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> #import "YourClub.h" #import "Membership.h" #import "MyClass.h" int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; MyClass *class1 = [[MyClass alloc] init]; @try { [class1 release]; } @catch (NSException *exception) { NSLog(@"Caught %@ %i", [class1 name], [class1 age]); } @finally { NSLog(@"OK"); } [pool release]; return 0; }
int *prt;//指针的类型是int*
int **prt;//指针的类型是int**
int (*ptr)[3]//指针的类型是int(*)[3]
int *(* ptr)[4]//指针的类型是int*(*)[4]
从语法上看,只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型,例如上面的:
int *prt;//指针的类型是int
int **prt;//指针的类型是int*
int (*ptr)[3]//指针的类型是int()[3]
int *(* ptr)[4]//指针的类型是int*()[4]
从上面可以看出,指针的类型(即指针本身的类型)和指针所指向的类型是两个概念
线程暂时没用到,先不做学习,等用到的时候在回来看P134
单例模式,P135,挺好的一种设计模式,能在例子中学习到静态方法+
// // main.m // test // // Created by Zeng on 13-5-24. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> @interface Singleton : NSObject{ NSString *name; int age; } @property(nonatomic, copy) NSString *name; @property int age; @end @implementation Singleton @synthesize name, age; static Singleton *singleton = nil; // 单例的主要方法 +(Singleton *)getSingleton{ if (singleton == nil) { singleton = [[super allocWithZone:NULL]init]; } return singleton; } +(id)allocWithZone:(NSZone *)zone{ return [[self getSingleton] retain]; // 返回单例 } -(id)copyWithZone:(NSZone *)zone{ return self; } -(id)retain{ return self; } -(NSUInteger)retainCount{ return NSUIntegerMax; } -(void)release{ } -(id)autorelease{ return self; } @end int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Singleton *singleton = [Singleton getSingleton]; [singleton setName:@"zengraoli"]; [singleton setAge:36]; NSLog(@"name : %@, age is : %i", [singleton name], [singleton age]); Singleton *singleton2 = [Singleton getSingleton]; NSLog(@"name : %@, age is : %i", [singleton2 name], [singleton2 age]); [pool release]; return 0; }
这里只需要注意方法重写和重载就行,不过这又和C++的差不多了
1、方法名相同
2、方法名的参数表必须不同,包括参数的类型和个数,以此区分不同的方法体
3、方法的返回类型、修饰符可以相同,也可以不同
OC没有像java那样,所谓的abstract类
id类型的使用,主要是可以取代*,和指针的使用差不多
// // main.m // test // // Created by Zeng on 13-5-24. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> #import "YourClub.h" #import "Membership.h" #import "MyClass.h" int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; id idMyClass; MyClass *class1 = [[MyClass alloc] init]; [class1 setName:@"zengraoli1" andSetTheAge:36]; MyClass *class2 = [[MyClass alloc] init]; [class2 setName:@"zengraoli2" andSetTheAge:63]; idMyClass = class1; NSLog(@"name : %@, age : %i", [idMyClass name], [idMyClass age]); idMyClass = class2; NSLog(@"name : %@, age : %i", [idMyClass name], [idMyClass age]); [class1 release]; [class2 release]; [pool release]; return 0; }
category是OC里面最常用到的功能之一。category可以为已经存在的类增加方法,而不需要增加一个子类。另外,category使得我们在不知道某个类的内部实现的情况下,为该类增加方法。
如果我们想增加某个框架(framewordk)中的类的方法,category就非常有效。比如,如果想在NSString上增加一个方法来判断它是否是一个URL,那可以这么做:
#import @interface NSString (Utilities) - (BOOL) isURL @end
P156、P157试一个使用category的例子
注意,类别并不能为类声明新的实例变量,它只包含方法。
NSStringUtiities.h
// // NSStringUtiities.h // test // // Created by Dawn on 13-5-27. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> #import "Cocoa/cocoa.h" @interface NSString (Utilities) -(BOOL) isURL; @end
NSStringUtiities.m:
// // NSStringUtiities.m // test // // Created by Dawn on 13-5-27. // Copyright (c) 2013年 zeng. All rights reserved. // #import "NSStringUtiities.h" @implementation NSString (Utilities) -(BOOL) isURL{ if ([self hasPrefix:@"http://"]) { return YES; }else{ return NO; } } @end
main.m:
// // main.m // test // // Created by Zeng on 13-5-24. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> #import "NSStringUtiities.h" int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *string1 = @" http://www.baidu.com"; NSString *string2 = @"Ozr"; if ([string1 isURL]) { NSLog(@"string is URL"); }else{ NSLog(@"string is not URL"); } if ([string2 isURL]) { NSLog(@"string isURL"); }else{ NSLog(@"string is not URL"); } [pool release]; return 0; }
上边的代码其实是对NSString做了一个小的扩展
OC中的宏定义和条件编译#ifndef跟C++中是一样的,需要注意这个:
如果在宏定义的参数之前防止一个#,那么在调用该宏的时候,预处理程序根据宏参数创建C语言风格的常量字符串。
例如:
#define str(x) #x
在后面的调用为str(test);得到的结果为"test"
Foundation Framework
可以查看方法的DOC-----------P170
// // main.m // test // // Created by Zeng on 13-5-24. // Copyright (c) 2013年 zeng. All rights reserved. // #import <Foundation/Foundation.h> #import "YourClub.h" #import "Membership.h" #import "MyClass.h" #import "NSStringUtiities.h" int main(int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSNumber *myNumber, *floatNumber, *intNumber; // 创建integer类型对象 intNumber = [NSNumber numberWithInteger:123]; NSLog(@"%li", [intNumber integerValue]); // 创建long类型对象 myNumber = [NSNumber numberWithLong:0xababab]; NSLog(@"%lx", [myNumber longValue]); // 创建char类型对象 myNumber = [NSNumber numberWithChar:'K']; NSLog(@"%c", [myNumber charValue]); // 创建float类型对象 floatNumber = [NSNumber numberWithFloat:123.9]; NSLog(@"%f", [myNumber floatValue]); // 创建double类型对象 myNumber = [NSNumber numberWithDouble:12233e+15]; NSLog(@"%lg", [myNumber doubleValue]); // 判断两个对象是否相等 if ([intNumber isEqualToNumber:floatNumber] == YES) { NSLog(@"值相等"); }else{ NSLog(@"值不等"); } // 比较两个对象的值大小 if ([intNumber compare:myNumber] == NSOrderedAscending) { NSLog(@"左边的数字小"); }else{ NSLog(@"左边的数字大"); } [pool release]; return 0; }
NSAutoreleasePool *pool =[[NOSAutoreleasePool alloc] init];
这行代码为我们分配了pool的自动释放池预留了内存空间。自动释放池可以自动释放添加到该池中的对象所使用的内存。当给对象发送一条autorelease消息时,就将该对象放到这个池中。释放这个池时,添加到该池中的所以对象都会一起被释放,因此所以这样的对象都会被销毁,除非已经指明了这些对象所在的作用域超出自动释放池。
NSInteger其实是typedef long
里面的方法可以通过查看DOC来使用