oc学习笔记2

时间:2024-04-15 23:03:46
.oc中的BOOL类型
oc中的BOOL类型的值为YES和NO,有点小奇怪
在oc中YES不等于1,但是NO一定等于0,所以不要把1和YES来比较 .消息发送
在oc中,经常使用这样的术语:将alloc消息发送给xxx类,实际上就是说调用了xxx类的类方法alloc
不过这点和java差别挺大的,上面所说的调用了xxx类的类方法,但是在java中能够使用类名调用的方法都是静态的(如果一个类继承了另一个类,另一个类中有一个方法是静态的,那么,难道能够使用子类.方法来时用父类的方法么?不能够把),但是oc上面的这种写法就是能够的。 .p141 代码清单8- 后面的评论有问题
myRect.origin = myPoint;
这句话中myRect类中实现了一个方法是setOrigin,然后就可以使用myRect.Origin来访问origin了么?
我知道如果使用@property origin;然后@implementation origin的话,是把origin的setter和getter方法实现了,但是如果定义一个setOrigin()方法,就说明是origin的setter方法么?编译器怎么知道的,我如果定义成setorigin的话,是否还是他的setter方法么?
还有 myRect.origin = myPoint;这行代码中应该使用了getter和setter方法,也就是说都使用了,但是在myRect.m文件中getter方法的定义是这个-int origin(),按理说这怎么对呢?getter方法不是应该在前面加上get,然后后面的单词第一个大些么?它这样定义怎么会对?
不理解中,回去要手动敲打一下
.p144 代码清单8- 后面的评论有问题 .创建一个新工程
ios:
ios:application,后面是7大模版,后面会用到,
我们先用这一个:Single View Appalication(模版)
下面工程名,第二个和第三个基本上用不上(公司中会用到)
下面devices,设备,ipad/iphone,下面3个选项比较简单,我们都不用,之后选择保留位置,点击创建,就创建一个项目文件了 左边栏会出现
HelloIphone中有.h,.m文件
Supporting Files:后面程序中用到的图片,图标
FrameWorks:框架,后面用的最多的是
Products:打包之后方的位置 .面向过程和面向对象的设计思想的区别
类和对象的概念
类和类之间的关系
对象和指针
如何定义一个类
初始化方法
对象的创建和使用
self和super关键字
static 关键字
@class和import的使用
类的继承
访问权限的控制
方法的重写
NSObject类
类的封装
类的多态 .oc类的声明和实现
@interface Person:NSObject
{
//实例变量声明
int identify;
int age;
}
//方法的生命
-(id)initWithAge:(int) _age identify:(int) _identify;
-(int)getIdentify;
-(int)getAge;
-(void)setAge:(int) _age;
@end 开发工具会自动生成@interface @end .实例变量:在java中我们说属性,但是在oc中我们说实例变量
在声明实例变量的时候不能为其初始化,系统默认会初始化。
实例变量的默认作用域范围是整个类 返回值类型:如果没有返回值,必须给出返回值类型为void .oc中进行方法调用中传递参数时,遵循值传递的原则:
基本数据类型传递的是该数据本身,指针类型传递的是对象的指针,而不是对象本身 -(id)initWithAge:(int) _age identify:(int) _identify;
这个方法的名字是initWithAge+identify
也就是说这个方法是两个名字和在一起的名字,每个参数都对应一个说明。 .oc中方法的调用有两种:
[类名或者对象名 方法名];
对象名.方法名(点语法) .xcode中创建一个工程步骤
File->new->project->osx:application->command line tool->project name:Person,next->save as。
创建一个类:
点击main.m,右键->new file->ios:cocor touch:object-c class->class:输入类名(Person),subclass of:NSObject->next->finish
会自动生成一个person.h和person.m文件
#import <Foudation/Foudation.h>
@interface Person:NSObject
{
int identify;
int age;
} -(id) initWithAge:(int)_age identify:(int) _identify;
-(int) getIdentify;
-(int) getAge;
-(void) setAge:(int)_age;
@end
方法的实现,可以先把.h中的内容复制然后拷贝到.m文件中,进行改写,Person.m文件如下:
#import "Person.h"
@implementation Person -(id) initWithAge:(int)_age identify:(int) _identify
{
//初始化父类,如果成功返回对象本身self(动态类型对象id)如果失败,返回nil
if(self =[super init]){
age = _age;
identify = _identify;
}
return self;
}
-(int) getIdentify
{
return identify;
}
-(int) getAge:(int)_age
{
age = _age;
}
-(void) setAge:(int)_age; @end #import <Foudation/Foudation.h>
#iimport <Person.h>
int main(int argc, const char * agrv[])
{
@autoreleasepool{
NSLog(@"Hello,World!");
Person *person;
person =[[Person alloc] init];
NSLog(@"person:%p",person);
}
return ; } .oc里面get方法,前面不写get,因为get这个关键字在oc中有特定的含义,对于上面的实例变量age,对应的getter方法就是Age,注意第一个字母大写。
NSString *s;
s=[[NSString alloc]initWithString:@"hello iPhone4s"]
使用alloc方法创建一个NSString类型的对象并用s指向它,以后可以通过s完成对其的操作 .如何在内存中区分类和对象
类是静态的概念,存放在代码区
对象是alloc出来的,存放在堆区,类的每一个实例变量在不同的对象中都有不同的值(静态变量除外)
方法也只是在被调用的时候,程序运行的时候才占用内存 .oc中对象通过指针来声明。如:ClassA *object;
oc中对象的创建:
使用alloc来创建一个对象,编译器会给object对象分配一块可用的内存地址。然后需要对对象进行初始化即调用init方法,这样这个对象才可以使用。如:
Person *person =[Person alloc];
person = [person init]; 上面使用方法嵌套调用(简化操作),如:
ClassA *object=[[ClassA alloc] init]; .通过约定,我们要求初始化方法一init开头,并且在成功完成初始化后,返回一个动态类型对象(id),也就是对象本身(也可以说是self),如果失败返回nil。 .指定初始化方法:
在一个类中,具有最完整的初始化参数的初始化方法通常就是指定初始化方法。
子类的初始化方法必须先调用父类的制定初始化方法,通过向super发送相应的消息初始化父类,相反,他们将调用参数比自己多的其他初始化方法(通过向self发送消息),并为自身没有的参数提供初始化值。在此调用序列中,最终将会调用到指定初始化方法,完成初始化过程。下面是一个实例:
-(id)init
{
[self initWithTitle:]
}
-(id)initWithTitle(NSString *)aTitle
{
[self initWithTitle:aTitle data:[NSDate date]];
}
-(id) initWithTitle:(NSString *)aTitle date:(NSDate *)aDate
{
if(self=[super init]){
title = [aTitle copy];
date =[aDate copy];
}
return self;
} .java中的访问修饰符:
修饰符 同类 同包 子类 全局
private 是
default 是 是
protected 是 是 是
public 是 是 是 是 oc中的访问修饰符:
修饰符 类内部 子类 任何地方
private 是
protected 是 是
public 是 是 是 private: 和java中的相同
protected:同类和子类中可以访问(也就是说这个类体内),也是默认的
public:都可以访问
修饰符后面不能加分号,加上会报错的(补充一点,可以使用指针运算符来访问实例变量,也就是->,但是这违背了面向对象的思想,一般我们不这么干) .oc和java一样,只支持单继承
不过通过协议可以实现多继承
注,oc中方法没有对应的访问修饰符,修饰符只对实例变量有用 .全局变量:
在一个文件中的类定义,方法定义之外进行定义,如:
int gGlobalVal =;
这个变量就是全局变量,如果想要在其他的地方使用它,需要使用extern进行生命,如:
想要在a.m中进行使用在方法中使用的话
extern int gGlobalVal; 这个时候的访问范围只有方法内
如果在a.m的开头(也就是方法和类的外边使用上面这句话的话),那么这个gGlobVal全局变量可以在本文件的任何地方进行使用
总结一下,也就是说如果想要使用全局变量的话,就需要extern int gGlobalVal一句话进行声明 .静态变量:
Person.m
#import...
static int gCount =;
@implementation Person
....
@end 在Person.m这个文件中的任意一个方法都可以使用(也就是说在此文件中是全局的),但是在其他的文件中就不可以使用了 .两个方法是否重名:
在oc中判断两个方法是否相同只有一个地方
就是方法名是否相同,和返回值与参数名没有关系 .self指的是类对象本身, self用来调用本类对象的方法
是类隐藏的参数,指向当前调用方法的类,(注:另一个隐藏参数时_cmd,代表当前类方法的selector,我不是很清楚)
super是父类本身,用来调用父类的方法
super并不是隐藏的参数,它只是一个“编译器指示符”,它和self指向的是相同的消息接收者。 实际上self和java中的this相同,而super和java中的super相同 .和java一样,使用对象+class可以拿到对应的类名,如:
[self class]
[super class]或者[self suerclass]可以拿到父类的名称 .@class和#import
实际上是为了解决循环引用导致死锁的问题
#import会包含这个类的所有信息,包括实体变量和方法
@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你
一般来说@class是放在interface中,也就是说在.h中,只是为了在interface中引用这个类,把这个类作为一个类型来用的。
而#import一般用在实现类中,即.m文件中,比如:
Student.h
#import <foundation/Foundation.h>
@interface Student:NSObject
{
int age;
int className;
}
-(int)getClassName;
@end
Student.m
#import "Student.h"
@implementation Student
-(int)getClassName
{
return className;
}
@end
如果在另一个.m想要使用Student这个类定义变量的话,如下:
PersonSelf.h
#import <foundation/Foundation.h>
@class Student //这个地方只用到了student这个类,所以说只用@class就可以了
@interface PersonSelf
{
int age;
NSString *name;
Student *s;
}
@end 假如在PersonSelf.m中的-(id)init方法中使用了
[Student alloc]等相关函数的话,那么在PersonSelf.m中就要引入#import Student.h文件了 .xcode build设置
点击工程名,后面窗口界面会自动显示出build setting设置页面,对应的下面有一个architectures,这里面可以改成32位的或者64位的 .oc里面术语:设置器和访问器
实际就是setter方法和getter方法和java中的一样,只是说oc中可以使用指令略去自己进行书写 .@property()括号中可以填的属性:
readwrite:默认
readonly:只读,意味着没有set方法
assign:默认,引用计数不增加
retain:引用计数增加1,这个针对的是对象类型,像int,double等基本数据类型,retain不起作用
actomic:默认,原子性型,线程保护机制,防止没有完成的时候,被其他的线程打断
nonatomic:非原子性的 .点语法:
oc中的方法调用有两种形式
一种是使用[]中括号的形式,叫做消息传送,发送
两外一种方式就是使用点语法了
如:
person.myNumber =;这个和
[person myNumber:];是相同的, 注意,能使用点语法的都是有property属性的,也就是说在property中定义的,如果没有在property中定义,那么就不能使用点语法了(不过貌似在4.0以上都是可以使用的了) .继承:
@interface 子类:父类 方法的重载
条件:定义一个同名的新方法,新方法必须具有相同的返回类型,并且参数个数与重载的方法相同
在java中应该和java的方法覆盖的概念一样(java中也有重载的概念,但是和oc里面的完全不同,呵呵) .多台,动态绑定
动态类型:只有在运行的过程中才能是什么类型。
id car2;在oc中是通过id来声明一个变量,就是动态类型 动态绑定:程序在执行时才确定对象调用的实际方法 多态:一种事物的多种形态。不同类的对象可以定义相同名称的方法,这就是多态的表现形成 多态的条件:有继承关系,有方法重写,父类的声明变量指向子类对象 下面这些是oc的动态绑定的一些方法,可以判断在运行期某个对象是否响应摸个事件。
-(BOOL)iskindOfClass:(Class)aClass; 对象是不是aClass或者子类的成员
-(BOOL)isMemberOfClass:(Class)aClass; 对象是不是aClass成员
-(BOOL)isSubclassOfClass:(Class)aClass; 对象是不是aClass子类
-(BOOL)respondsToSelector:(SEL)aSelector;对象是否能响应aSelector指定的方法
-(BOOL)performSelector:(SEL)aSelector;对象调用aSelector指定的方法
-(BOOL)performSelector:(SEL)aSelector;
withObject:(id)object;对象调用aSelector指定的方法,传递参数object
-(BOOL)respondsToSelector:(SEL)aSelector;
withObject:(id)object1;
withObject:(id)object2;对象调用aSelector指定的方法,传递参数object1和object2 (BOOL)respondsToSelector:(SEL)aSelector: //对象是否响应@selector指定的方法
if([car respondsToSelector:@selector(run)]){
NSLog....
}
上面这个if判断中,很显然,car对象对应的类定义了run方法,那么这个respondsToSelector:@selector调用就能够响应,返回就为true了,if就满足了 .SEL关键字
SEL action
action = @selector(run);
[car performselector:action];//这几行代码是使用了动态绑定的技术
[car performselector:action];其中performselector作用就是前面这个对象直接调用后面action指定的方法
上面这个SEL声明一个东在,在运行运行期间调用selector指定的run方法
上面这段代码等同于:
[car performSelector:@selector(run)];一般情况下写成这种形式简介一些 .判断两个对象是否是同一类型,可以如下判断
if([Audi class] ==[Benz class]){
NSLog...
}
可以看到使用了[类名 class]的方式直接与另外一个进行==判断,这在oc中是这样操作的,java中是不允许这么干的
(另外,记得貌似使用 [对象名 class]可以获得对象的类名,如[self class],可见oc中两者都可以 .oc中的异常处理
@try
...
@catch
...
@finally
...
好的方法是在出现问题时把异常抛出来,然后通过日志把异常纪录下来(一般在大型项目中使用)
在@catch(NSException *exception){
NSLog(@"catch exception %@ %@",[exception name],[exception reason]);
} .Foundation 框架
数字对象常用处理方法
字符串对象常用处理方法
数组对象常用处理方法
字典和集合对象常用处理方法 在foundation框架中,你会发现都是以NS开头,这个是因为它来自于cocoa,看到NS就应该知道是乔布斯从NextSTEp带过来的,为了区别苹果的现有的一些库 .数字对象:NSNumber
和java中的基本数据类型和对应的类类型一样 数字对象的初始化:就是把一个基本类型进行一个封装
//类方法创建数字对象
int number = ;
NSNumber *intNumber = [NSNumber numberWithInt:number];
BOOL isBool = YES;
NSNumber *boolNumber = [NSNumber numberWithBool:isBool];
//下面是和前面的操作基本上一样,只是前者不需要我们去管理内存,而下面需要我们手动去管理内存的
float pi = 3.14;
NSNumber *piNumber = [[NSNumber alloc] initWithFloat:pi];
char character = 'a';
NSNumber *cNumber = [[NSNumber alloc] initWithBool:isBool]; //有包装,就有对应的还原,下面是几个还原的方法:
int month = [intNumber intValue];
BOOL isopen = [boolNumber boolValue];
float length = [piNumber floatValue];
char firstName = [cNumber charValue]; int main()
{
@autoreleasepoo{
//创建一个NSNumber对象
NSNumber *monthNumber = [NSNumber numberWithInt:];
NSNumber *lengthNumber = [NSNumber alloc] initWithInt:10.8];
NSlog(@"mothNumber :%@",mothNumber);
NSlog(@"lengthNumber :%@",lengthNumber); //还原成基本数据类型
int month = [mothNumber intValue];
float length = [lengthNumber intValue];
NSlog(@"moth :%d",moth);
NSlog(@"length :%d",length);
NSNumber *monthNumber = [NSNumber numberWithInt:];
NSNumber *monthNumber = [NSNumber numberWithInt:];
@... } .字符串的基本概念和常用处理方法:NSString类
为了区别于c语言,oc的字符串必须以@开头,此外,NSString对象一旦被创建,就不能再修改,如果需要一个可以更改的字符串对象,需要创建NSMutableString实例(实际上是NSString的子类) 字符串的创建
//创建一个字符创常量
NSString *string =@"这是一个字符串常量"
//创建一个空的字符串
NSString *string =[[NSString alloc] init];//这是一个实例方法
NSString *string =[NSString string];//这是一个类方法
//快速创建一个字符串,下面两句注意这个地方创建的字符串不在堆内存上面,在常量区(和第一句的 NSString *string =@"这是一个字符串常量" 都是在常量区的)
//如果两个对象内容相同的话,那么他们是相等的(因为他们指向的是同一个地址,这个和java中的字符串类似)
NSString *string=[[NSString alloc] initWithString:@"快速创建字符串"];
NSString *string=[[NSString stringWithString:@"快速创建字符串"];
//快速创建一个格式化字符串:这个是创建在堆区的
int number =;
NSString *string=[[NSString alloc] initWithFormat:@"%",number];
float number = 2.4;
NSString *string=[[NSString alloc] initWithFormat:@"浮点数%f",number];
//比较字符串是否相同:isEqualToString
//比较字符串的大小: caseInsensitiveCompare,如:
NSComparisonResult result =[string10 caseInsensitiveCompare:string11];
NSLog(@"result:%d",result);
//其实上面NSComparisonResult是一个枚举类型(也就是基本数据类型)
//判断依据是美国的信息交换码来进行判断是升序还是降序的。 字符串的转换
//改变字符串的大小写
NSString *hello = @"hello WORLD";
NSlog(@"%@",[hello uppercaseString]); //全部大写
NSlog(@"%@",[hello lowercaseString]);//全部小写
NSlog(@"%@",[hello capitalizedString]);//首字母大写,其他字母小写
//将字符串转换成基本数据类型
NSString *string = @"2.467";
NSlog(@"%d",[string boolValue]); //转换成BOOL类型
NSlog(@"%f",[string flatValue]); //转换成浮点型
NSlog(@"%f",[string doublelValue]); //转换成双精度型
NSlog(@"%d",[string intValue]); //转换成整型 //将字符串转换成数组
NSString *string = @"One Two Three Four";
NSArray *array = [string ComponentsSeparatedBystring:" "];
NSLog(@"array:%@",array); //字符串的截取与拼接
//截取字符串
NSString *string = @"abcdefg";
NSArray *subString1 = [string substringToIndex:];
NSArray *subString2 = [string substringFromIndex:];
NSLog(@"subString1:%@",subString1);
NSLog(@"subString2:%@",subString2);
NSRange range;//注意这个NSRange是一个结构体
range.location =;
range.length=;
NSArray *subString3 = [string substringWithRange:range];
NSLog(@"subString3:%@",subString3);
//拼接字符串
NSString *str1 =@"",*str2=@"";
NSString *string=[[NSString alloc] initWithFormat:@"这是拼接:%@ and %@",str1,str2];
NSString *string1=[str1 stringByAppendFormat:@"%@",str2];
NSString *string2=[str1 stringByAppendString:str2];
//注意上面这几个方法并没有改变原来的字符串内容,只是返回一个新的字符串 //字符串查询
NSString *link = @"asdastarget=_blankddasd";
NSRange range = [link rangeOfString:@"target=_blank"];
if(range.location !=NSNotFound){
NSlog(@"string找到了");
} //可变字符串:NSMutableString,他继承自NSString
NSMutableString *mutableString1 = [[NSMutableString alloc] initWithFormat:@"abc"];
//插入字符串
[mutableString1 insertString:@"...xyz" atIndex:];
NSLog(@"mutableString1:%@",mutableString1);
//替换字符串
[mutableString1 replaceCharactersInRange:NSMakeRange(,) withString:@"efg"];
NSLog(@"mutableString1:%@",mutableString1);
//删除字符串
[mutableString1 deleteCharactersInRange:NSMakeRange(,)];
NSLog(@"mutableString1:%@",mutableString1); .集合-数组的概念和常用方法
NSArray,NSMutableArray:是一组有序的对象集合
数组有可变和不可变之分。
数组中不可以存放基本数据类型,只能存放类的实例(对象)。
如果想要把基本数据类型,结构体放入数组总,需要通过NSNumber,NSValue进行数据的封装
NSArray:不可变数组
数组的初始化:(对应的也有类方法和实例方法之分,下面只列出类方法)
NSArray *array1 = [NSArray arrayWithObject:@"one"];//这个是不可变的数组,并且就一个元素,实用性不强
NSArray *array2 = [NSArray arrayWithObjects:@"one",@"two",nil];//注意这个一定要以nil结尾
NSArray *array3 = [NSArray arrayWithArray:array2];
NSArray *array4 = [NSArray arrayWithContentOfFile:path];
//获取数组中的元素个数和访问
int count = [array2 count];
NSLog(@"array2 all element :%d",count);
NSString *string1=[array2 bojectAtIndex:]; //注意,这个地方时下标从0开始的
NSLog(@"element of array:%@",string1);
//在原有的数组上追加对象,返回一个新的数组对象
NSArray *addArray = [array2 arrayByAddingObject:@"add"];
//用指定的字符串将数组中的元素连接起来
NSString *arrayStr = [array componentsJoinedByString:@","];
//数组中是否包含某个对象
BOOL isContain = [array containObject:@"bbb"];
//查询指定对象在数组中的元素,如果没有此元素,返回NSNotFound
NSInteger index = [array indexOfObject:@"ccc"];
//获取数组中最后一个元素
NSString *lastString = [array lastObject]; NSMutableArray:可变数组,继承自NSArray
//常用方法:
NSMutableString *mutableArray = [NSMutableArray arrayWithCapacity:];
//向数组中添加一个元素
[mutableArray addObject:@"aaa"];
//向数组指定下标添加元素
[mutableArray insertObject:@"ccc" atIndex:];
//移除最后一个元素
[mutableArray removeLastObject];
//移除指定元素
[mutableArray removeObject:@"aaa"];
//移除指定下边元素
[mutableArray removeObjectAtIndex:];
//向数组中添加数组
[mutableArray addObjectsFromArray:array];
//替换指定的下标元素
[mutableArray replaceObjectAtIndex: withObject:@"replace"];
//移除所有对象
[mutableArray removeAllObjects];
//遍历数组常规方法,如:
NSArray *array2 = [NSArray arrayWithObjects:@"one",@"two",nil];
int length =[array count];
for(int i=; i<length; i++){
NSString *element=[array objectAtIndex:i];
NSLog(@"%@",element);
}
//快速枚举(这个和java中的快速遍历差不多吧)
for(NSString *string in array){
NSLog(@"found %@",string);
}
//当不确定数组元素的类型时,可以选择使用id
for(id *string in array){
NSLog(@"found %@",string);
} .集合-字典基本概念和常用用法
有键-值组成的数据集合(这个和java中的map差不多)
通过key(键),查找对应的value,key通常是字符串对象,也可以是其他的任意数据类型对象,在一个字典对象中,key的值必须是唯一的,并且key和value不可以为空(nil),如果在一个字典对象中表示一个空值,可以使用NSNull对象
NSDictionary-不可变字典
//初始化:
NSNumber *numObj = [NSNumber numberWithInt:];
//以一个元素初始化
NSDictionary *dic =[NSDictionary dictionaryWithObject:numObj forKey:@"key"];
//以两个元素初始化
NSDictionary *dic =[NSDictionary dictionaryWithObjectsAndKeys:numObj,@"key",numObj2,@"valueKey2",nil];
//初始化新字典,新字典包含otherDic
NSDictionary *dic =[NSDictionary dictionaryWithDictionary:otherDic];
//以文件内容初始化字典
NSDictionary *dic =[NSDictionary dictionaryWithContentsOfFile:path];
//获取字典数量
NSInteger count =[dic count];
//通过key获取对应的value对象
NSObject *valueObject =[dic objectForKey:@"key"];
//将字典的key转换成一个枚举对象,用于遍历
NSEnumerator *emumerator = [dic keEmumerator];
//获取所有键的集合
NSArray *keys= [dic allKeys];
//获取所有值的集合
NSArray *values = [dic allValues]; NSMutableDictionary-可变字典,继承与NSDictionary
//常用方法:
NSMutableDictionary *dic2 =[NSMutableDictionary dictionaryWithObjectsAndKes:@"v1",@"key1",@"v2",@"key2",nil];
//向字典2对象中添加整个字典对象3
NSDictionary *dic3 =[NSDictionary dictionaryWithObject:@"v3" forKey:@"key3"];
[dic2 addEntriesFromDictionary:dic3];
//初始化一个空的可变字典
NSMutableDictionary *dic1 = [NSMutableDictionary dictionary];
//将空字典1对象内容设置于字典2对象相同
[dic1 setDictionary:dic2];
将字典中key1对应的值删除
[dic1 removeObjectForKey:@"key1"];
//根据制定的数组(key)移除字典2中的内容
NSArray *array=[NSArray arrayWithObjects:@"key1",@"key2",nil];
[dic2 removeObjectsForKeys:array];
//移除字典所有对象
[dic1 removeAllObjects]; 遍历字典
//快速枚举
for(id key in dic){
id obj = [dic objectForKey:key];
NSLog(@"%@",obj);
}
//一般的枚举
NSArray *keys = [dic allKeys];
int length = [keys coutn];
for(int i=; i<length; i++){
id key = [keys objectAtIndex:i];
id obj = [dic objectForKey:key];
NSLog(@"%@",obj);
}
//通过枚举类型枚举
NSEmumerator *emumerator =[dic keyEmumerator];
id key = [emumerator nextObject];
while(key){
id obj = [dic objectForKey:key];
NSLog(@"%@",obj);
key = [enumerator nextObject];
} .集合-集合基本概念和常用方法
不可变集合NSSet:单值对象的集合,元素无序(和java中的set是一样的)
初始化:
//类似与数组的构建,直接创建一个集合
NSSet *set1 =[[NSSet alloc] initWithObjects:@"one",@"two",nil];
//通过数组的构建集合
NSArray *array = [NSArray arrayWithObjects:@"",@"",@"",nil];
NSSet *set2 =[[NSSet alloc] initWithArray:array];
//通过已有集合构建集合
NSSet *set3 =[[NSSet alloc] initWithSet:set2]; NSSet常用方法
//集合3中对象的个数
int count = [set3 count];
//以数组的形式返回集合3中所有的对象
NSArray *allObjects = [set3 allObjects];
//返回集合3中的任意一个对象
id object = [set3 anyObject];
//集合4中是否包含内容为2的字符串对象,如果包含返回YES,否则NO
BOOL isContain = [set4 containsObject:@""];
//集合4中与集合2中是否存在有相同元素的对象,如果有返回YES,否则为NO
BOOL isIntersect = [set4 intersectsSet:set2];
//集合4与集合5中的元素是否完全匹配,如果匹配返回YES,否则NO
BOOL isEqual = [set4 isEqualToset:set5];
//集合4是否是集合5的子集合,如果是返回YES,否则返回NO
BOOL isSubset = [set4 isSubsetOfSet:set5];
//创建一个新的集合2,集合2有两个兑现(a和b)
NSSet *set1 = [NSSet setWithObjects:@"a",nil];
NSSet *set2 = [set1 setByAddingObject:@"b"];
//通过已有的集合7和集合8,创建一个集合9
NSSet *set7 = [NSSet setWithObjects:@"a",nil];
NSSet *set8 = [NSSet setWithObjects:@"z",nil];
NSSet *set9 = [set7 setByAddingObjectsFromSet:set8];
//通过已有的集合10和数组对象,创建一个新的集合11
NSSet *array = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];
NSSet *set10 = [NSSet setWithObjects:@"z",nil];
NSSet *set11 = [set10 setByAddingObjectsFromArray:array]; 可变集合-NSMutableSet,他继承自NSSet
常用方法:
//创建一个空的集合
NSMutableSet *set1 = [NSMutableSet set];
NSMutableSet *set2 = [NSMutableSet setWithObjects:@"",@"",nil];
NSMutableSet *set3 = [NSMutableSet setWithObjects:@"a",@"",nil];
//集合2减去集合3中的元素,集合2最后元素只有1个,且为1
[set2 minusSet:set3];
//集合2与集合3中元素的交集,集合2最后元素只有1个,且为2
[set2 intersectSet:set3];
//并集,集合2最后元素有3个,为1,2,a
[set2 unionSet:set3];
//将空集合1内容设置成集合3中的内容
[set1 setSet:set3];
//在set2的基础上添加一个新的数组
[set2 addObjectsFromArray:array];
//删除
[set2 removeObject:@""];
[set2 removeAllObjects]; .类的扩展
类目的基本概念和用法
延展的基本概念和用法
协议基本概念和用法
委托设计模式的概念和用法 .类目的基本概念和用法
类目(category),在《object-c2.0程序设计》中说的是分类。
我们又是会碰到这样一种情况:比如我们封装了一个类,不想再动他了,可是随着程序功能的增加,需要在那个类中增加一个小小的方法,这时我们不必子类定义修改原来的类,只用随手添加一个类的分类,也就是类目即可。
()在类目定义的方法,会成为原始类的一部分,与其他的方法调用没有区别
()通过给父类定义类目方法,其子类也会继承这些方法,但是如果子类添加类目方法,父类则不会拥有子类的类目方法。 类目的应用(有点):
对现有类进行了扩展:比如,你可以扩展Cocoa touch框架中的类,你在类目中增加的方法会被子类所继承,而且在运行时和其他的方法没有区别
作为子类的替代手段:不需要定义和使用一个子类,你可以通过类目直接向已有的类中增加方法。
对类中的方法归类:利用category把一个庞大的类分为小块分别进行开发,从而更好的对类中的方法进行更新和维护
类目方法的局限性:
无法向类目中添加新的实例变量,类目中没有位置来容纳实例变量,如果想增加类的实例变量,只能通过定义子类的方式。
假如在类目中覆盖现有的方法,可以会引起super消息的断裂,因为类目中的方法具有更高的优先级,因此,一般不要覆盖现有的方法。 类目的命名和用法
命名规则:类目+扩展方法:如"NSString+Revert"
类目的接口声明与类的定义十分相似,但类目不继承父类,只需要带有一个括号,表明类目的主要用途。
举例说明:
.h中类目的定义
#import <Foundation/Foudation.h>
@interface NSString (Revert)
- (void)test;
@end
.m中类目的实现
#import "NSString+Revert.h"//注意这个NSString+Revert.h就是这个字符串,不是说代表什么,xcode里面自动生成的就是相+字符串为名字的.h
@implementation NSString (Revert)
- (void)test
{
}
@end
可以发现和普通类的声明与定义没有什么区别 可以把多个类目和原始类定义在一个.h文件中,这个是允许的(这样也是有好处的,利于对类进行分类管理,利于开发和维护)。在oc的源码中,如NSArray的类声明中,就在一个.h中定义了很多的类目。
对于定义部分,仍然可以放到一个.m文件中来实现。 .延展的基本概念和用法
延展:如同"匿名"的类目,即把类目声明中()中间的内容空着(就是没有名字,这才叫匿名吧)
延展中声明的方法(其实,一般在.m文件中中来进行延展的声明,因为延展定义的方法一般是私有的,那么放到.h中就是公开的了,这样的话放到.m中就变成私有的了,此时,声明和定义都在同一个.m文件中了)在类本身的@implementation和它的@end之间实现(这样的话,其实和原始类中的普通方法定义一样了)
在oc中,我们知道方法是没有public,private修饰的(也就是说oc中的方法都是public的)类有时需要定义一些方法是私有的,这个时候我们就可以通过延展的方式定义类的私有方法