標籤:
Block(oc 的資料類型,很常用,本質是c結構體)
類似內嵌函式,從原始碼層看,有函數的結構,而在編譯後,卻不具備函數的性質。編譯時間,類似宏替換,使用函數體替換調用處的函數名
Block封裝了一段代碼,可以在任何時候執行
Block可以作為函數參數或者函數的傳回值,而其本身又可以帶輸入參數或傳回值。
蘋果官方建議盡量多用block。在多線程、非同步任務、集合遍曆、集合排序、動畫轉場用的很多
Blocks的定義:
int (^MySum)(int, int) = ^(int a, int b) { return a+b;};
定義了一個叫MySum的blocks對象,它帶有兩個int參數,返回int。等式右邊就是blocks的具體實現,Block可以訪問局部變數,但是不能修改。
Block 類似一個語句,比如10;
int sum = 10;int (^MyBlock)(int) = ^(int num) { sum++;//編譯報錯 return num * sum;};
如果要修改就要加關鍵字:__block
__block int sum = 10;
能訪問全域變數且也能修改全域變數
Blocks和函數指標對比(類似)
定義函數指標
int (*myFn)();
定義Blocks
int (^MyBlocks)(int,int);
調用函數指標
(*myFn)(10, 20);
調用Blocks
MyBlocks(10, 20);
Blocks的賦值
在聲明的同時定義變數,然後賦值
int (^MySum)(int,int) = ^(int a,int b) { return a + b;};
也可先用typedef先宣告類型,再定義變數進行賦值
typedef int (^MySum)(int,int);MySum sum = ^(int a,int b) { return a + b;};
block要掌握的東西
1> 如何定義block變數(兩種)
int (^sumBlock)(int, int);void (^myBlock)();
2> 如何利用block封裝代碼
^(int a, int b) {return a - b;};^() {NSLog(@"----------");};
3> block訪問外面變數
* block內部可以訪問外面的變數
* 預設情況下,block內部不能修改外面的局部變數
* 給局部變數加上__block關鍵字,這個局部變數就可以在block內部修改
4> 利用typedef定義block類型
typedef int (^MyBlock)(int, int);// 以後就可以利用MyBlock來定義block變數MyBlock block;MyBlock b1, b2;b1 = ^(int a, int b) {return a - b;};MyBlock b3 = ^(int a, int b) {return a - b;};
protocol簡單使用(很常見)基本用途
用來聲明一大堆方法(不能聲明成員變數),僅僅是聲明!
只要某個類遵守了這個協議,就相當於擁有這個協議中的所有方法聲明
只要父類遵守了某個協議,就相當於子類也遵守了
協議的編寫
@protocol 協議名稱// 方法聲明列表@end
某個類遵守協議
@interface 類名 : 父類 <協議名稱>@end
協議中有2個關鍵字可以控制方法是否要實現(預設是@required),在大多數情況下,用途在於程式員之間的交流
- @required:這個方法必須要實現(若不實現,編譯器會發出警告)
- @optional:這個方法不一定要實現
協議遵守協議
- 一個協議可以遵守其他多個協議,多個協議之間用逗號 , 隔開
- 一個協議遵守了其他協議,就相當於擁有了其他協議中的方法聲明
@protocol 協議名稱 <協議1, 協議2>@end
基協議
- NSObject是一個基類,最根本最基本的類,任何其他類最終都要繼承它
- 其實還有一個協議,名字也叫NSObject,它是一個基協議,最根本最基本的協議
- NSObject協議中聲明很多最基本的方法,比如description、retain、release等
- 建議每個新的協議都要遵守NSObject協議
定義變數時指定協議
// NSObject類型的對象,並且要遵守NSCopying協議NSObject<NSCopying> *obj;// 任何OC對象,並且要遵守NSCoding協議id<NSCoding> obj2;
在 xcode6裡建立協議的方法:oc file 裡如下類似視窗(包括建立分類也是如此)
建立.h 檔案,因為協議就是用來聲明方法的。標頭檔裡聲明即可。
// MyProtocol.h#import <Foundation/Foundation.h>// 定義了一個名叫MyProtocol的協議@protocol MyProtocol <NSObject>// @required 要求實現,不實現就會發出警告// @optional 不要求實現- (void)test4;@required- (void)test;- (void)test2;@optional- (void)test3;@end// MyProtocol2.h#import <Foundation/Foundation.h>@protocol MyProtocol2 <NSObject>- (void)haha2;@optional- (void)haha3;@end// MyPrototol3.h#import <Foundation/Foundation.h>#import "MyProtocol.h"// 一個協議遵守了另外一個協議,就可以擁有另一個協議的所有方法聲明@protocol MyProtocol3 <MyProtocol>- (void)hehe;@end/*檔案名稱:Person.h */#import <Foundation/Foundation.h>@class Hashiqi;@protocol MyProtocol2;@protocol MyProtocol3;// 只要一個類遵守了某一份協議,就能擁有這份協議中的所有方法聲明// : 繼承// <> 遵守協議@interface Person : NSObject <MyProtocol3, MyProtocol2>@property (nonatomic, strong) id<MyProtocol2> obj;@property (nonatomic, strong) Hashiqi *dog;@end/*檔案名稱:Person.m*/#import "Person.h"#import "MyProtocol2.h"#import "MyProtocol3.h"@implementation Person- (void)test{}@end// MyProtocol4.h#import <Foundation/Foundation.h>@protocol MyProtocol4 <NSObject>@end/*檔案名稱:Dog.h */#import <Foundation/Foundation.h>@protocol MyProtocol2;@interface Dog : NSObject <MyProtocol2>@end/*檔案名稱:Dog.m*/#import "Dog.h"#import "MyProtocol2.h"@implementation Dog- (void)haha2{}@end/*檔案名稱:Hashiqi.h */#import "Dog.h"@protocol MyDogProtocol <NSObject>- (void)dogTest;@end@interface Hashiqi : Dog<MyDogProtocol>- (void)addTest;@end@interface Hashiqi (Add)- (void)addTest;@end/*檔案名稱:Hashiqi.m */#import "Hashiqi.h"@implementation Hashiqi- (void)dogTest{}@end@implementation Hashiqi (Add)- (void)addTest{}@end// Hashiqi+MJ.h#import "Hashiqi.h"@interface Hashiqi (MJ)@end// Hashiqi+MJ.m#import "Hashiqi+MJ.h"@implementation Hashiqi (MJ)@end// main.m#import <Foundation/Foundation.h>#import "MyProtocol.h"#import "MyProtocol3.h"#import "Person.h"#import "Dog.h"#import "Hashiqi.h"int main(){ Person *p = [[Person alloc] init]; p.obj = [[Hashiqi alloc] init]; return 0;}void test(){ //NSObject *obj = [[NSObject alloc] init]; //NSObject *obj2 = @"4324324"; // 要求obj3儲存的對象必須是遵守是MyProtocol這個協議 //NSObject<MyProtocol> *obj3 = [[NSObject alloc] init]; NSObject<MyProtocol> *obj3 = [[Person alloc] init]; obj3 = nil; //id 相當於 NSObject * id<MyProtocol> obj4 = [[Person alloc] init]; obj4 = nil; // 要求obj5,儲存的對象必須遵守MyProtocol3、並且繼承了Person Person<MyProtocol3> *obj5 = [[Person alloc] init]; obj5 = nil;}
協議的定義
@protocol 協議名稱 <NSObject>
// 方法聲明列表....
@end
如何遵守協議
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> 定義在原來類中的分類,只要求能看懂文法
objective-c 文法快速過(8)