++ Category ++分类(类扩展)

可以动态的为已经存在的类添加新的方法(但不能添加成员变数);(Xcode中新建-Object-C file-选择category;)[可以和头文件写在同一个文件中(一个文件中可有多个类)]

不需要创建子类;实现的方法的模块化;

//需要导入要扩展的类的头文件;

#import 「Student.h"

//类名后有一个()就代表著是一个分类;

//(..)中的内容就是分类的名称;

@interface Student (addFound)

-(void)test2;//扩展的方法声明

@end

使用场景:需求变更;对系统基础类库进行扩展;

++ protocol ++

概念:就是一系实现方法的列表,其中声明的方法可以被任何类实现,这种模式称为代理(delegation)模式(同Java中的介面);

(在iOS和OS x开了中,采用了大量的代理模式来实现MVC中的View(UI控制项)和Controller(控制器)的解耦,如按钮监听);

[命名规范 **Delegate,如ButtonDelegate;]

在头文件中定义:

@class Button;

//<>代表实现了某个协议(类似于java中该介面继承了另一个介面)

@protocol ButtonDelegate <NSObject>

-(void)onClick:(Button *)button;//一般规范要添加调用的对象

@end

@interface Button : NSObject

//定义一个按钮的监听器,不知道返回类型,用id代替,<ButtonDelegate>表示该协议是实现了ButtonDelegate

//还需要手动释放内存

@property (nonatomic,retain) id<ButtonDelegate> delegate;

-(void)onClick;

@end

创建一个listener实现这个协议:

//#import 「Button.h」//不用导入,但在.m文件中需导入的protocol文件

@protocol ButtonDelegate;//作用同@class

@interface OnClickListener : NSObject <ButtonDelegate>

-(void)onClick;

@end

并在触发时调用:

@implementation Button

-(void)onClick{

//按钮被点击了;

//先判断调用的对象是否实现了该方法

if([_delegate respondsToSelector:@selector(onClick:)]){

[_delegate onClick:self];

}else{

NSLog(@"未实现该方法");

}

}

使用:

//初始化一个按钮

Button *btn = [[[Button alloc] init] autorelease];

//初始化一个按钮监听器

OnClickListener *listener = [[[OnClickListener alloc] init] autorelease];

//将监听器添加到按钮上

btn.delegate = listener;

[btn onClick];

(原则谁触发,传入谁)在使用协议下的方法下,一般传入调用的对象;如当某个按钮点击时,一般传入该按钮;

— 同java,可单独定义多个协议,且一个类也有实现多个协议:

定义protocol文件

@protocol Study <NSObject>

@required //必须实现的方法,虽然是必须实现,但是编译器不会出错,OC是弱语法的,对类型要求不严格

-(void)testStudy;

//若不写,默认是@required

-(void)testStudy1;

@optional //可实现可不实现

-(void)testStudy2;

@end

一个类可同时实现多个protocol:

//同时实现两个协议(相当于java中实现两个介面)

@protocol Study,Learn;

@interface Student : NSObject<Study,Learn>

在对象调用实现的协议方法时,可先判断是否实现:

void testProtocol(){

Student *stu =[[[Student alloc] init] autorelease];

//判断student是否遵守了Study协议

if ([stu conformsToProtocol:@protocol(Study)]) {

NSLog(@"student是遵守了Study协议");

}

//判断student是否实现了某个方法;

if([stu respondsToSelector:@selector(testStudy)]){

NSLog(@"student 实现了testStudy方法");

[stu testStudy];

}else{

NSLog(@"student没有实现testStudy方法");

}

}

++ Block ++苹果建议尽量多使用block,在多线程,非同步任务,集合遍历,集合排序,动画转场用的很多。[同java中的回调];

封装了代码,可以在任何时候调用执行;(类型于java中直接在使用的时候new一个onClickListenre)

Block可作为函数参数或函数的返回值;而其本身可带输入参数的返回值。它和传统的函数指针很类似;但有区别:block是inline(内联函数),并默认情况下对局部变数是只读的。(可定义在方法内部和外部)

使用:

//使用别名声明一个带两个参数的block

typedef int(^MySum) (int,int);

void testBlock(){

//第一种方式:直接定义;^是block的标志,定义了一个block,接收两个int类型的参数,并返回一个int类型;

int (^Sum)(int,int) = ^(int a,int b){

return a+b;

};

NSLog(@"sum is %i",Sum(10,11)) ;

__block int c = 19;

//第二种方式:使用声明的block

//可以访问外部的成员,但不能修改(同java中介面中访问外部变数用final)

//若要访问,外部的变数须用__block修饰

MySum sum = ^(int a,int b){

c = 20;

NSLog(@"c is %i",c);

return a+b;

};

NSLog(@"sum is %i",sum(10,31)) ;

}

实现按钮监听:

在button.h中:

//定义一个block别名格式: 返回类型 (^名字)(参数)

typedef void (^ButtonBlock)(Button *);

@property (nonatomic,assign) ButtonBlock listener;

"在button.m中在onClick中方法中调用:

_listener(self);"

使用:

Button *btn = [[[Button alloc] init] autorelease];

btn.listener = ^(Button *btn){

NSLog(@"listener onclick %@",btn);

};

[btn onClick];

和指针函数的区别:

int sumFound(int a,int b){

return a+b;

}

void testBlockAndPoint(){

//定义了Sum这种block类型

typedef int (^Sum)(int,int);

//定义了sump这种指针类型

typedef int (*SumP)(int,int);

//定义了一block变数

Sum sum = ^(int a,int b){

return a+b;

};

NSLog(@"block sum 和%i",sum(1,2));

//指针函数指向实现的方法

SumP p = sumFound;

NSLog(@"point sum %i",p(2,3));

}

++OC 相关基础类 ++

都位于Foundation(类似于java中的lang包,java中有基础类都有对应的类)

结构体 +:位于Foundation/NSRange下

typedef struct _NSRange {

NSUInteger location;

NSUInteger length;

} NSRange;

这个结构体表示事物的一个范围,通常是字元串里的字元范围或集合里的元素范围;location(该范围的起始位置)length(该范围内元素的个数)。

三种创建方式:

*逐个赋值;

*聚合赋值NSRange range={3,4};

*Foundation提供的一个快捷函数:NSRange range = NSMakeRange(8, 10);

//直接全部列印,但不能直接使用rang,需使用NSString转换

NSLog(@"%@",NSStringFromRange(range));

NSPoint p;

p.x = 20;

p.y = 37;

NSLog(@"%@",NSStringFromPoint(p));

常用结构体:NSSize,NSPoint,NSRange,NSRect;

(都有对应的生成方法 NSMake***(..) ;列印方法 NSStringFrom***(.) ;绘制类生成方法 CG***Make(..)方法;)

++ 字元串+

NSString:不可变(同java中的String);

指向指针的指针,将原变数的地址作参数传入函数中,可修改传入的原变数的值;

void testStringFromFile(){

//从文件中读取字元串

// NSString *path =@"/Users/sionfan/work/ddd.txt";

//另一种读取文件的方式url

NSURL *path = [NSURL URLWithString:@"file:///Users/sionfan/work/ddd.txt"];

//定义一个错误变数,传入,若有值,则有错误信息;

NSError *error;

//指定字元串编码UTF8;

NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];//此处要对传入的error赋值,则要把error的地址传入才能对其赋值;(参数是指向指针的指针)

if (error==nil) {

//没有错误信息,则文件读取成功

NSLog(@"读取文件成功str:%@",str);

}else{

NSLog(@"读取文件失败:%@",error);

}

//也可以读取网页;

NSURL *urlPath = [NSURL URLWithString:@"百度一下,你就知道"];

NSError *httpError;

//读取URL

NSString *str2 = [NSString stringWithContentsOfURL:urlPath encoding:NSUTF8StringEncoding error:&httpError];

NSLog(@"读取网页成功str:%@",str2);

}

/**参数是指向指针的指针,传入str的地址&str,就可对传入的原变数进行修改;*/

void testModofyStr(NSString **str){

*str = @"this is 修改后的str";

}

+(void)testString{

//C中的字元串

char *str = "this is a C string";

//1.这种方式创建的方式不需要自己释放内存

NSString *str1 = @"this is a OC string";

//2.这种方式需要手动释放内存

NSString *str2 = [[NSString alloc] init];

str2 = @"this is a OC init string";

//3.同上,直接带参数创建

NSString *str3 = [[NSString alloc] initWithString:@"this is initwith Stirng"];

//4.不带@,将C的的字元串转换成OC的字元串;

NSString *str4 = [[NSString alloc] initWithUTF8String:"this is c string"];

//5.带格式符的字元串

NSString *str5 = [[NSString alloc] initWithFormat:@"my age is %i,and height is %.2f",18,1.87];

//上面对应的方法都是自己创建的,需要手动释放内存;在NSString都有如下对应的静态方法,可不用手动释放内存;

//此处可能存在两个错误,1.上面自己创建的对象未释放,会内存泄露;2,后面用静态方法创建的对象自己已经释放,再手动释放会造成野指针错误

str5 = [NSString stringWithString:@"this is static string"];

// [str5 release];

NSLog(@"%s
,%@
,%@
,%@
,%@
,%@
",str,str1,str2,str3,str4,str5);

testStringFromFile();

//传入str的地址,可在执行完函数后修改原变数的值

testModofyStr(&str5);

NSLog(@"%@",str5);

}

NSSting *str = @「345」;345没有名字,只有一个指针str指向存储了345字元串的这块地址;

+字元串导出+

NSString *str = @"this is a export str";

//若文件不存在,会自动创建

//但若文件夹不存在,会自动报错

NSString *path =@"/Users/sionfan/work1/ddda.txt";

NSError *error;

//atomically,原子性操作(先创建一个临时文件,将文件一点点到这个临时文件中,再拷贝到目标文件中);非原子性操作:直接向文件中写入;(优先考虑原子性操作,可考虑写入安全)

[str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];

if (error) {

//获取本地重要错误信息,类似于java的e.getMessage()

NSLog(@"写入失败:%@", [error localizedDescription]);

}else{

NSLog(@"写入成功");

}

}

++ String相关方法 +

uppercaseString: 全部转成大写

lowercaseString:全部转成小写

capitalizedString:只是首字母转成大写

[@"abc" isEqualToString:@「Abc」]:比较两个字元串内容是否相同(相同返回1)

[@"abc" compare:@「Abc」]:比较字元串大小;(返回一个枚举值:三个值:NSOrderedAscending = -1L(右边的大), NSOrderedSame(相同), NSOrderedDescending(左边大))

[@"abc" caseInsensitiveCompare: @「Abc」]:忽略大小写比较,返回值同上;

[str hasPrefix:@「stu」]:str是否以stu开头;

[str hasSuffix:@「.jsp」]:str是否以.jsp结尾;

[str rangeOfString:@「stu」]:查看stu在str的位置和长度;返回一个NSRang的结构体(用NSStringFromRang列印),未找到返回NSNotFound(NSIntegerMax);if(range==NSNotFound)未找到;

(同java,若有多个相同的字元,则只返回第一个位);

[另带同名方法,带参数:options(指定搜索选项,如搜索顺序等):range :(指定一个范围进行搜索)]

[str substringFromIndex:2]:从index = 2开始截取末尾;

[str substringToIndex:2]:从开头截取到index=2处;

[str substringWithRange:NSMakeRange(2, 4)]:从index=2开始截取4个字元;

[str componentsSeparatedByString:@「.」]:以.分组(同java是split方法);返回NSArray;

[NSString pathWithComponents:paths]:将一个(NSMutableArray *paths)数组拼成一个路径

[str pathComponents]:将一个路径分解成一个数组;

[path isAbsolutePath]:表示一个路径是否是绝对路径(实际上就是判断开始位置有无/)

[path lastPathComponent]:返回一个路径最后个目录

[path stringByDeletingLastPathComponent]:返回删掉最后一个目录后的路径;

[path stringByAppendingPathComponent:@「work」]:在路径最后拼接一个目录,并返回拼接后的路径

[path pathExtension]:返回一个文件路径该文件的扩展名(就是.后的内容);

[str stringByDeletingPathExtension]:删掉扩展名;

[str stringByAppendingPathExtension:@「html」]):拼接一个扩展名(自动加.);

[str stringByAppendingFormat:@「%i」,2]):拼接一个带格式符的字元串

[str intValue]:将内容是int类型的string转成int(同java中String.valueOf),另外double,float都有对应的方法;

[str length]:返回字元串的字元个数

[str characterAtIndex: 6]:返回index=6处的字元

[str UTF8String]:将一个OC的字元串转成一个C的字元串;

++ NSMutableString +可变长字元串(同java中StringBuilder),是NSString的子类,其父类的方法都可用;

[一般对象中带有 Mutable ,就表示是一个可变的对象]

//长度可变,可先在初始化时指定容量大小,就会预先分配10个字数的存储空间,效率高一些;

NSMutableString *ms = [[NSMutableString alloc] initWithCapacity:10];

//设置字元串内容

[ms setString:@"1234"];

//直接拼接

[ms appendString:@"567"];

//拼接带占位符的字元串

[ms appendFormat:@"age is %i",23];

//替换指定位置和长度的字元串,一般与rangeOfString全用进行文本替换

[ms replaceCharactersInRange:NSMakeRange(2, 2) withString:@"eed"];

//在index=3的位置插入指定的字元串

[ms insertString:@"insert" atIndex:3];

//删除指定位置和长度的字元串

[ms deleteCharactersInRange:NSMakeRange(3, 2)];

NSLog(@"%@",ms);

// [ms release];

推荐阅读:

相关文章