- 快速枚举
Objective-c 2.0中引入了快速枚举,它提供了一种简单而优雅的方式来枚举集合中的元素,比如数组和集合。它增加了一个for- loop循环,使用简洁的for/in语法来迭代集合
NSArray *colors = [NNArray arrayWithObjects:
@"Black",@"Silver",@"Gray",nil]
for(NNString *colors in colors)
{
Printf("Consider buying a %s car", [color TUT8String]);
}
二、创建单例UIApplicartion 和UIDevice类支持访问当前正在运行的应用程序和它运行所基于的设备硬件的相关信息。为此他们提供了单例,即当前进程中一个类的单一实例。
例如,[UIApplication SharedApplication]返回一个单例,可以报告它使用的委托的相关信息。
构建一个单例所需要的代码量极少,只需要在类实现中定义一个静态饿共享实例,然后添加一个指向该实例的类方法。
@implementation ViewIndexer
static ViewIndexer *sharedInstance = nil;
+(ViewIndexer * ) sharedInstance{
if(!sharedInstance)
sharedInstance =[[self alloc] init];
return sharedInstance;
}
//Class behavior defined here
@end
要使用这个单例,调用[ViewIndexer sharedInstance]. 这将返回共享对象,并允许访问单例提供的任何行为。通过覆盖allocWithZone :方法可以防止任何类创建第二个实例。
+ (id) allocWithZone : (NSZone *) zone
{
@synchronized(self){
if (sharedInstance == nil)
{
sharedInstance = [super allocWithZone:zone];
return sharedInstance;
}}
return nil;
}
三、类别
代码清单: 为UIDevice 类构建一个Orientation 类别
@interface UIDevice (Orientation)
@property (nonatomic, readonly) BOOL isLandscape;
@end
@implementation UIDevice (Orientation)
- (BOOL) isLandscape
{
return (self.orientation == UIDeviceOrientationLandscapeLeft) ||
(self.orientation == UIDeviceOrientationLandscapeRight);
}
@end
三、Foundation 类
1、字符串
NNString *myString = @"A string constant";
NNString *myString = [ NNString stringWithFormat :@"The number is %d",5];
NSLog = ( @"%@", [myString stringByAppendingString:@"22"]);
附加格式化提供更大的便利:
NSLog = ( @"%@", [myString stringByAppendingString:@"%d",22]);
长度与索引字符
NSLog(@"%d",myString.length);
printf("%c",[myString characterAtIndex:2]); //打印数组号为2的字符 即 e
2、使用日期
下面的代码说明了如何使用当前时间创建一个新日期对象,以及如何使用一个时间间隔来表示未来(或过去的某一时间)
//current time
NSDate *date =[NSDate date];
//time 10 seconds from now
date= [NSDate dateWithTimeIntervalSinceNow: 10.0f];
格式化日期:
NNDateFormatter *formatter =[[NNDateFormatter alloc] init];
[formatter autorelease];
formatter.dateFormat = @"YYYY-MM-dd HH:mm;ss";
NNString *timestamp = [formatter stringFormDate:[NSDate date]];
NSLog(@“ %@”,timestamp);
四、集合
iPhone 主要使用三类集合: 数组、字典、和集
1、构建和访问数组
使用便利方法arrayWithObjects:创建数组,它返回一个自动释放的数组,调用次方法时,列出要添加给数组的所以方法,并使用空值完成列表。
NSArray *array = [ NSArray arrayWithObjects: @"One",@"Two", @"Three",nil];
可变数组是可编辑的。NSArray 的可变形式是NSMutableArray 。借助可变数组,可随意增加和删除对象。
NSMutableArray *marray = [NSMutableArray arrayWithArray : array];
[marray addObject:@"Four"];
[marray removeObjectIndex:2];
NSLog(@"%@",marray);
2、检查数组
可测试一个数组是否包含某个对象,并恢复指定对象的索引。
如: if([marray containsObject:@"Four"])
NSLog(@"The index is %d", [marray indexofObject:@"Four"]); //如果数组中包含“Four”这个对象,打印索引位置。
接口是对象的类应该提供特性的描述。接口不提供实现的细节
实现是是接口正常工作的代码。
在Objective-C 中只要看到@ 符号,都可以把它看成C语言的扩展@interface Circle告诉编译器:“这是为名为Circle的新类定义的接口”;
@interface 用于定义类的公共接口。通常,接口被称做API“application programming interface” 中3个首字母的缩写。使对象真正起作用的代码位于 @implementtation部分中。
3、Objective -C 不支持多继承,但是可以通过其他特性获取多继承的有点,例如分类和协议。
改变方法的实现时,需要重写 (Override),代码运行时,Objective-C 确保调用相应类的重写方法的实现。
记住每个方法调用都获得了一个名为self 的隐藏参数,他是一个指向接收消息的对象的指针。方法使用self 参数查找它们要使用的实例变量。
Objective-C 提供某种方式来重写方法,并且任然调用超类的实现方式。当需要超类实现自身的功能,同时在前面或后面执行某些额外的工作时,这种机制非常有用。为了调用继承方法的实现,需要使用super 作为方法调用的目标。
4、复合
编程中的复合就好像音乐中的作曲一样:将多个组建组合在一起配合使用,从而得到完整的作品。
在Objective -C中,复合是通过包含作为实例变量的对象指针实现的。严格来讲,只有对象间的组合才能叫做复合。
@interface Car : NSObject
{
Engine * engine;
Tire *tires[4];
}
- (void) print;
@end //Car
实现
@implementation Car
- (id) init
{
if(self = [super init]){
//这一句话是什么意思呢?若要超类可以完成所需的一次性初始化,需要调用【super init】,init 方法返回的值(id 型数据,即范型对象指针)描述了被初始话的对象。将【super init】的结果赋给self 是Objective - C的标准惯例,这么做是防止超类在初始化的过程中返回的对象不同于原先创建的对象。
engine = [Engine new ];
tires[0] = [Tire new];
tires[1] = [Tire new];
tires[2] = [Tire new];
tires[3] = [Tire new];
}
return (self);
} //init
- (void) print{
NSLog(@"%@",engine);
NSLog(@"%@",tires[0]);
NSLog(@"%@",tires[1]);
NSLog(@"%@",tires[2]);
NSLog(@"%@",tires[3]);
@end //Car
主函数 main()
且来看看Objective- C的主函数
int main(int args, const char *argv[]){
Car *car; //声明
car = [Car new]; //创建
[car print]; //打印自身信息
return(0); //退出程序
} //main
防御式编程 一般写在setter 函数中。
复合是OOP 的基本概念,我们用这种技巧来创建引用其他对象的对象
存取方法和复合是密不可分的,我们通常都会为复合的对象编写存取方法。
两种类型的存取方法:setter方法和 getter 方法,前者告诉对象将属性改为什么,后者要求对象提供属性的值。
---------------------------------------------------------------------------------------------------
@class 创建了一个前向引用。就是在告诉编译器:“相信我,你以后会知道这个到底是什么,但是现在,照个面就可以了”;
如果有循环依赖关系,@class 也很有用,即A类使用B类,B类也使用A类。如果试图通过#import 语句让这两个类互相引用,那么最后就会出现编译器错误。但是在A.h 中使用 @class ,在B.h 中使用@class ,那么这两个类就可以互相引用了。