OC--Foundation架構
一些其他知識總結
Block 注意:大括号後面一定有分号 ;
形式:^( 形參 ) { 内容代碼 };當沒有形參是可以^{ 内容代碼 };
格式:傳回類型 (^Block名稱) (形參) = ^( 形參 ){ 内容代碼 };
傳回類型 ( ^Block名稱) (形參) ; // 傳回類型可以是void
Block名稱 = ^( 形參 ) { 内容代碼 };
例如:// 計算兩個整數的和
#import <Foundation/Foundation>
Int main()
{
// int (^BlockSum)( int,int )= ^(int a,int b){ return a + b; };
int (^BlockSum)( int,int ) ;
BlockSum = ^(int a,int b){
return a + b;
};
int c = BlockSum( 8, 7);
NSLog( @ “%d”, c );
}
用typedef簡化Block // 計算兩個整數的和
typedef傳回類型 ( ^新名稱) (形參) ;
新名稱 變量名 = ^(形參){ 内容 };
typedef int ( ^MyBlock ) ( int , int );
MyBlock sumBlock = ^(int a, int b){
return a + b;
};
int c = sumBlock( 5, 8 ); // 調用<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
@protocol @end 協定:用來聲明方法
1. 基本用途
* 可以用來聲明一大堆方法(不能聲明成員變量)
* 隻要某個類遵守了這個協定,就相當于擁有這個協定中的所有方法聲明
* 隻要父類遵守了某個協定,就相當于子類也遵守了
2. 格式
* 協定的編寫
@protocol 協定名稱
// 方法聲明清單
@end
* 某個類遵守協定
@interface 類名 : 父類 <協定名稱>
@end
3. 關鍵字
協定中有2個關鍵字可以控制方法是否要實作(預設是@required),在大多數情況下,用途在于程式員之間的交流
* @required:這個方法必須要實作(若不實作,編譯器會發出警告)
* @optional:這個方法不一定要實作
4. 協定遵守協定
* 一個協定可以遵守其他多個協定,多個協定之間用逗号 , 隔開
* 一個協定遵守了其他協定,就相當于擁有了其他協定中的方法聲明
@protocol 協定名稱 <協定1,協定2>
@end
5. 基協定
* NSObject是一個基類,最根本最基本的類,任何其他類最終都要繼承它
* 其實還有一個協定,名字也叫NSObject,它是一個基協定,最根本最基本的協定
* NSObject協定中聲明很多最基本的方法,比如description、retain、release等
* 建議每個新的協定都要遵守NSObject協定
當我們隻是引用某個類或協定時,隻需要@[email protected]
當我們需要使用某個類或協定時,必須#importxx.h
1.協定的定義
@protocol 協定名稱 <NSObject>
// 方法聲明清單....
@end
2.如何遵守協定
1> 類遵守協定
@interface 類名 : 父類名 <協定名稱1, 協定名稱2>
@end
2> 協定遵守協定
@protocol 協定名稱 <其他協定名稱1, 其他協定名稱2>
@end
3.協定中方法聲明的關鍵字
1> @required (預設)
要求實作,如果沒有實作,會發出警告
2> @optional
不要求實作,怎樣不會有警告
4.定義一個變量的時候,限制這個變量儲存的對象遵守某個協定
類名<協定名稱> *變量名;
id<協定名稱> 變量名;
NSObject<MyProtocol> *obj;
id<MyProtocol> obj2;
如果沒有遵守對應的協定,編譯器會警告
[email protected]中聲明的屬性也可用做一個遵守協定的限制
@property (nonatomic, strong) 類名<協定名稱> *屬性名;
@property (nonatomic, strong) id<協定名稱> 屬性名;
@property (nonatomic, strong)Dog<MyProtocol> *dog;
@property (nonatomic, strong)id<MyProtocol> dog2;
6.協定可用定義在單獨.h檔案中,也可用定義在某個類中
1> 如果這個協定隻用在某個類中,應該把協定定義在該類中
2> 如果這個協定用在很多類中,就應該定義在單獨檔案中
7.分類可用定義在單獨.h和.m檔案中,也可用定義在原來類中
1>一般情況下,都是定義在單獨檔案
2> 定義在原來類中的分類,隻要求能看懂文法
*/
協定代理
雙方通過協定建立關系,其他的類,隻要遵守協定都可以成為代理
例如人去買票,可以找一個人(受雇者)去幫買,隻要某個類通過協定,都可以是收雇者
是以我們必須在Person類中,寫好協定代理
@interface Person : NSObject
- (void) buyTicket;
// 擁有一個代理屬性
// id代表代理的類名随便
// 但必須遵守TicketDelegate協定
@property (nonatomic, retain)id<TicketDelegate> delegate;
@end
隻要某個代理遵守了某個協定,并實作了該協定的方法,都可以成為代理
Agent.m檔案
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Agent : NSObject<TicketDelegate>
@end
Agent.m檔案
#import "Agent.h"
@implementation Agent
// 剩餘的票數
- (int)leftTicketsNumber
{
// ... 親自跑電影院\或者打電話
return 1;
}
// 每一張票多少錢
- (double)ticketPrice
{
// ... 親自跑電影院\或者打電話
return 1000;
}
@end
Main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Agent.h"
#import "NextAgent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Person *p = [[[Person alloc] init] autorelease];
NextAgent *a = [[[NextAgent alloc] init] autorelease];
p.delegate = a;
[p buyTicket];
}
return 0;
}
這樣Person類不用改,隻要其他類遵守協定即可
Foundation架構
函數 CG開頭的函數要導入架構:CoreGraphics
NSRange
NSPoint\CGPoint
NSSize\CGSize
NSRect\CGRect
1、 NSRange 參數:lacation length
*rangeOfString:@”字元”
* 求響應字元在字元串中的起始位置和長度
* 如果找不到,length= 0, location = NSNotFound = -1
代碼示例
int main()
{
NNString *str = @” i love heima”;
//通過調用rangeOfString查找字元串”love”在str中的位置和長度
NSRange range = [ str rangeOfString:@”love” ];
//如果能找到字元串”love”,則傳回” love”在str中的位置和長度
//如果找不到字元串”love”,則傳回length = 0,location = -1;
NSLog(@”loc = %d, length = %d”,range.location, range.length);
}
2、NSPoint\CGPoint // 定義一個點的坐标
NSPoint p1 =NSMakePoint(10,10);
CGPoint p2 = CGPointMake(10,10); // 最常用
CGPointZero // 表示原點,等價于CGPointMake(0,0)
//輸出時可以
NSLog(@”x = %f, y = %f”,p1.origin.x, p1.origin.y );
//或者轉換成字元串在輸出
NNString * str = NSStringFromPoint(p1);
NSLog(@”%@”,str ); // { 10,10}
3、NSSize\CGSize // 定義寬和高
NSSize p3 =NSMakeSize (100,50);
CGSize p4 = CGPointSize (100,50); // 最常用
CGSizeZero //等價于CGPointSize (0,0)
輸出時可以
NSLog(@”width= %f, height = %f”,p3.size.width, p3.size.height );
或者轉換成字元串在輸出(常用)
NNString * str = NSStringFromsize(p3);
NSLog(@”%@”,str ); // { 100,50}
4、NSRect\CGRect //定點開始的寬和高
CGRect r1 = CGRectMake(1, 4 , 6, 7);
CGRect r2 = { {2, 3}, {5, 8}};
CGRect r2 = { p1, p3};
CGRect r2 = { CGSizeZero, CGPointZero};
CGRectZero // {{0, 0}, {0 , 0}}
//字元串輸出
NNString * str = CGRect(r2);
NSLog(@”%@”,str ); //{ {2, 3}, {5, 8}}
5、比較傳回BOOL類型,成立傳回1 不成立傳回0
BOOL b = CGPointEqualtToPoint(CGPointMake(12, 12), CGPointMake(12,12) );
// 類似函數CGSizeEqualtToSize CGRectEqualtToRect
CGRectEqualtToPoint // 判斷某個點是否在這個範圍内
BOOL d = CGRectEqualtToPoint(CGRectMake(50, 40, 100, 50), CGPointMake(90,70)
NSLog(@”%d”,d); // 成立傳回1 不成立傳回0
1.NSString類的操作
使用NSString類的對象初始化方法建立字元串
建立無參數的字元串
NSString *str2 = [[NSString alloc] initWithString:@"Jack"];
建立帶參數的字元串
NSString *str3 = [[NSString alloc] initWithFormat:@"age is %d",10];
C字元串 轉換為 OC字元串
NSString *str4 = [[NSString alloc] initWithUTF8String:"Rose"];
OC字元串 轉換為 C字元串
const char c = [str4 UTF8String];
讀取檔案内容第一種方式:
讀取桌面下 getWeather.xml 檔案裡的所有内容
NSString *str5 = [[NSString alloc] initWithContentsOfFile:@"/Users/apple/Desktop/getWeather.xml" encoding:NSUTF8StringEncoding error:nil];
NSUTF8StringEncoding 适用于使用中文的編碼格式
讀取檔案内容第二種方式
URL:資源路徑 格式為:協定頭://
比如本地檔案的URL格式:file://
網絡檔案的URL格式:http://
伺服器檔案的URL格式:ftp://
NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/apple/Desktop/getWeather.xml"];
如果通路網絡就可以定義:http://www.baidu.com
NSString *str6 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; NSLog(@"/n%@",str6);
使用NSString類方法建立字元串
建立無參數的字元串
NSString *str2 = [NSString stringWithString:@"Jack"];
建立帶參數的字元串
NSString *str3 = [NSString stringWithFormat:@"age is %d",10];
C字元串 轉換為 OC字元串
NSString *str4 = [NSString stringWithUTF8String:"Rose"];
讀取檔案内容第一種方式:
讀取桌面下getWeather.xml檔案裡的所有内容
NSString *str5 = [NSString stringWithContentsOfFile:@"file:///Users/apple/Desktop/getWeather.xml" encoding:NSUTF8StringEncoding error:nil];
NSUTF8StringEncoding 适用于使用中文的編碼格式
讀取檔案内容第二種方式:
讀取桌面下getWeather.xml檔案裡的所有内容
NSURL *url = [NSURL URLWithString:@"file:///Users/apple/Desktop/getWeather.xml"];
NSString *str6 = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
可以看出實作同一個功能NSString提供了對象方法和類方法兩種解決方式而類方法快捷友善,是以在實際開發中推薦使用類方法來操作字元串
将字元串寫入到一個檔案裡
給目标檔案中寫入字元串,兩種寫入方式在寫入之前都會将檔案中的内容全部清空後再寫入
第一種寫入方式
atomically參數指寫入不成功時要不要停止
[@",iOS" writeToFile:@"/Users/apple/Desktop/getWeather.xml"atomically:YESencoding:NSUTF8StringEncoding error:nil];
第二種寫入方式
NSString *content = @"iOS,Java";
NSURL提供了直接定義本地URL的類方法
NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/getWeather.xml"];
[content writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
2.NSMutableString類的操作
NSMutableString繼承自NSString
那麼NSMutableString可以使用NSString類中的任意方法 NSMutableString提供了自己獨有的方法
NSString *str = [NSString stringWithFormat:@"My age is 10 "];
NSString *str2 = [str stringByAppendingString:@"11 12"];
NSLog(@"%@",str2); // 列印:My age is 10 11 12
NSMutableString *mutalbeStr = [NSMutableString stringWithFormat:@"My age is 10 "];
[mutalbeStr appendString:@"11 12"];
// appendString方法沒有傳回值,說明是直接str字元串後面進行拼接
NSLog(@"%@",mutalbeStr); // 列印:My age is 10 11 12
可以看出:NSString一旦定義了str字元串它本身就不可變了,雖然NSString類方法也提供了拼接的方法如stringByAppendString方法但是它傳回的是一個新的字元串。 而NSMutableString提供的拼接方法appendString方法是在原有的字元串上直接拼接它沒有傳回值。這就是可變和不可變字元串的本質
// NSMutableString 提供了删除方法,比如說要删掉上面可變字元串中的11有兩種方式:
第一種 :
必須要清楚要删除内容的location和length,11在整個字元串中的loc = 11 length = 2 (不推薦使用) [mutalbeStr deleteCharactersInRange:NSMakeRange(13, 2)];
第二種:
先擷取要删除内容的範圍,然後删除範圍内的字元串
NSRange range = [mutalbeStr rangeOfString:@"11"];
[mutalbeStr deleteCharactersInRange:range];
NSLog(@"%@",mutalbeStr); // 列印:My age is 10 12
2.OC集合類的操作
(1) OC集合類包括NSArray,NSSet,NSDictionary都是以面向對象的方式操作數組,而且OC數組不像C語言中的數組隻能存放同一種資料類型,它可以存放任意類型的對象,但是不能存放非OC對象類型如基本資料類型int,struct,enum等 (2) OC數組是以對象的方式存在,是以在建立的時候需要為建立的對象前面加*
(3) NSArray數組一旦建立就決定了是不是可變,而且永遠是可變或不可變
(4) NSArray數組和子類NSMutableArray的基本操作
使用NSArray的類方法arry建立個數組
建立時定義為空數組,那麼array數組将永遠是空數組
NSArray *array = [NSArray array];
NSArray的常見操作:
建立數組對象有兩種方式
第一種方式:
NSArray *array = [NSArray arrayWithObjects:@"Jack",nil];
數組中包含了兩個NSString對象 nil是用來辨別數組元素結束的辨別
是以OC數組中不能存放空對象
NSArray *array1 = [NSArray arrayWithObjects:@"Jack",@"Rose", nil];
第二種方式:(推薦使用)
NSArray *array2 = @[@"Jack",@"Rose"];
擷取數組的長度
array1.count;
NSUInteger count = [array1 count];
NSLog(@"%ld",count);
通路數組中的對象的兩種方式
NSString *str1 = [array1 objectAtIndex:0];
數組中索引為1的對象,OC中提供的方法 傳回:Jack NSString *str2 = array1[0];
編譯器特性其實還是轉為上面的形式來通路 傳回:Jack
周遊數組的三種方式
第一種:
for (int i = 0; i<array1.count; i++)
{
NSLog(@"%@",array1[i]); // 數組中存放的是對象可以用%@輸出
if (i ==0) {
break;
}
}
第二種:
将array1數組中的每個對象拿出來賦給obj然後依次列印
for (id obj in array1)
{
// id obj 代表數組中的對象
// 擷取obj對象在數組中的索引
NSUInteger index = [array1 indexOfObject:obj];
NSLog(@"%ld-->%@",index,obj);
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
第三種:
使用Block 每次從數組中周遊一個元素後就傳遞給block,block也相應的執行一次
block中的id obj對應數組中的元素,NSUInteger idx對應數組中元素的索引 BOOL用來停止周遊
[array1 enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%ld-->%@",idx,obj);
// 如果索引為0 立即停止周遊
if (idx ==0) {
*stop = YES;
}
}];
NSMutableArray的基本操作:
建立可變數組
NSMutableArray *mutableArray = [NSMutableArray array];
NSMutableArray *mutalbeArray2 = @[@"張三",@"李斯"];
注意:@[]傳回的是不可變NSArray數組 這樣會報錯
為可變數組增加任意對象
Person *person = [[Person alloc] init];
[mutableArray addObject:person];
[mutableArray addObject:@"Jack"];
[mutableArray addObject:@"John"];
[mutableArray addObject:10]; 數組中不可以存放基本資料類型
從數組中删除指定的元素
[mutableArray removeObject:@"John"];
[mutableArray removeObjectAtIndex:0];
将數組中的元素全部删除
[mutableArray removeAllObjects];
NSSet數組和子類NSMutableSet的基本操作
NSSet和NSArray都是不可變數組,一旦建立就無法改變。
NSSet是無序的集合簡單操作:
建立NSSet集合
NSSet *set = [NSSet set]; // 一旦建立為空永遠為空
NSSet *set2 = [NSSet setWithObjects:@"Jack",@"Rose",@"Jim",nil];
随機擷取NSSet集合中的元素
NSString *str = [set2 anyObject];
NSLog(@"%@",str);
NSMutableSet的簡單操作:
建立可變set集合
NSMutableSet *mutableSet = [NSMutableSet set];
為set添加集合
[mutableSet addObject:@"Jack"];
[mutableSet addObject:@"Rose"];
删除元素
[mutableSet removeObject:@"Jack"];
(6) NSArray和NSSet數組的對比
都是可以存放任意類型的OC對象的集合,都不能存放基本資料類型 本身都是不可變的,但是子類都是可變的 NSArray是有序的集合,NSSet是無序的集合
(7) NSDictionary和NSMutableDictionary
NSDictionary和它的子類NSMutableDictionary都是以key/value的形式存在,NSDictionary本身為不可變集合 NSDictionary也是無序集合 字典集合中存儲的值是以鍵值對的形式存在,如果存在相同的key那麼後面key的值會被覆寫。但是允許vaule的重複
NSDictionary的基本操作
常見建立Dictionary集合的四種方式
1.建立一個空的字典集合類型
NSDictionary *dic = [NSDictionary dictionary]; // 一旦為空 永久為空
2.建立隻有一組值的字典集合
NSDictionary *dic1 = [NSDictionary dictionaryWithObject:@"Jack" forKey:@"name"];
3.建立多個值的字典集合
NSArray *keys = @[@"name",@"address",@"e-mail"];
NSArray *values = @[@"Jack",@"北京",@"[email protected]"];
NSDictionary *dic3 = [NSDictionary dictionaryWithObjects:values forKeys:keys];
4.通過值/鍵的方式來建立
NSDictionary *dic4 = [NSDictionary dictionaryWithObjectsAndKeys:
@"Jack",@"name", @"北京",@"address", @"[email protected]",@"e-mail",nil];
5.類似于數組的建立方式 (推薦使用)
NSDictionary *dic5 = @{@"name":@"Jack", @"address":@"北京", @"e-mail":@"[email protected]"};
取值:
根據相應的Key取出對應的值
NSString *name = [dic1 objectForKey:@"name"]; // 傳回 Jack // 傳回鍵值對的個數
NSUInteger count = dic5.count; // 傳回 4
周遊NSDictionary數組用兩種方式:
第一種方式:
擷取字典中所有的鍵
NSArray *allKeys = [dic5 allKeys]; // 擷取的鍵在數組中是無序的
for (int i = 0; i < dic5.count; i++) {
NSString *key = allKeys[i];
NSString *value = dic5[key];
NSLog(@"%@-->%@",key,value);
} <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
第二種方式:
将字典中的鍵值對傳遞給Block中的key和obj
[dic5 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"%@-->%@",key,obj);
// 周遊一次立即停止 *stop = YES;
}];
NSMutableDictionary的基本操作
建立可變字典
NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary];
NSMutableDictionary *mutableDic2 = @{@"name",@"Rose",@"address",@"北京"};
錯誤的寫法因為右邊傳回的是不可變的字典
為可變字典添加元素
[mutableDic setObject:@"Rose" forKey:@"name"];
[mutableDic setObject:@"北京" forKey:@"address"];
// 移除 [mutableDic removeAllObjects];
[mutableDic removeObjectForKey:@"name"];
// 列印 NSLog(@"%@",mutableDic);
// 輸出:address = "\U5317\U4eac"; name = Rose;
\U5317\U4eac 就是北京存儲的形式 複制代碼
(8) 設計一個通訊錄裡面包含了四個人的姓名、電話、位址 複制代碼
NSArray *friends = @[ @{@"name":@"張三",@"phone":@"13993214321",@"address":@"北京"}, @{@"name":@"李斯",@"phone":@"13498766789",@"address":@"上海"},
@{@"name":@"王武",@"phone":@"15898766789",@"address":@"天津"}, @{@"name":@"趙柳",@"phone":@"18798766789",@"address":@"南京"}];
// 擷取‘李斯’的通訊錄資訊
NSDictionary *dic = friends[1];
NSLog(@"%@",dic);