類似內聯函數,從源代碼層看,有函數的結構,而在編譯后,卻不具備函數的性質。編譯時,類似宏替換,使用函數體替換調用處的函數名
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 協議名稱// 方法聲明列表@end
某個類遵守協議
@interface 類名 : 父類 <協議名稱>@end
協議中有2個關鍵字可以控制方法是否要實現(默認是@required),在大多數情況下,用途在于程序員之間的交流
協議遵守協議
@protocol 協議名稱 <協議1, 協議2>@end
// 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;
如果沒有遵守對應的協議,編譯器會警告
5.@property中聲明的屬性也可用做一個遵守協議的限制
@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> 定義在原來類中的分類,只要求能看懂語法
新聞熱點
疑難解答