++ 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];

推薦閱讀:

相關文章