objective-c 文法快速過(8),objective-c文法

來源:互聯網
上載者:User

objective-c 文法快速過(8),objective-c文法
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;

如果沒有遵守對應的協議,編譯器會警告

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> 定義在原來類中的分類,只要求能看懂文法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.