OC-Block和協(xié)議

什么是 Block

  • Block 是iOS中一種比較特殊的數(shù)據(jù)類型

  • Block 是蘋果官方特別推薦使用的數(shù)據(jù)類型,應(yīng)用場(chǎng)景比較廣泛

    • 動(dòng)畫(huà)
    • 多線程
    • 集合遍歷
    • 網(wǎng)絡(luò)請(qǐng)求回調(diào)
  • Block 的作用

    • 用來(lái)保存某一段代碼,可以在恰當(dāng)?shù)臅r(shí)間再取出來(lái)調(diào)用
    • 功能有點(diǎn)類似于函數(shù)和方法
    • 可以保存代碼
    • 有返回值
    • 有形參
  • 標(biāo)志:^

  1. 沒(méi)有返回值,沒(méi)有形參
void (^JuneBlock)() = ^(){};

// 如果block沒(méi)有形參,可以省略后面的 小括號(hào)()
void (^JuneBlock)() = ^{};
  1. 有返回值,有形參
int (^JuneBlock)(int, int) = ^(int a, int b){
    return a + b;
};
  1. typedef 定義 Block
// 定義一個(gè)叫 MyBlock 的類型
// 利用 MyBlock類型 可以定義 block變量
// 利用 MyBlock類型定義出來(lái)的變量,存儲(chǔ)的代碼必須返回 int 必須接受 2個(gè)int類型的參數(shù)
typedef int (^JuneBlock)(int, int)

JuneBlock jBlock;

JuneBlock j1, j2;

j1 = ^(int a, int b){
    return a - b;
};

JuneBlock sumBlock = ^(int a, int b){
    return a + b;
};
  1. Block 訪問(wèn)外面變量
    1> Block 內(nèi)部可以訪問(wèn)外面的變量
    2> 默認(rèn)情況下,Block 內(nèi)部不能修改外面的局部變量
    3> 給局部變量加上 __block 關(guān)鍵字,就可以在 Block 內(nèi)部修改
int a = 10;

__block int b = 10;

void (^JuneBlock)() = ^{
  // 默認(rèn)情況下,block 內(nèi)不能修改外面的局部變量
  // a = 20;

  // 因?yàn)?變量 b 前面加了__block,所以變量 b 的值可以被修改 
  b = 20;
  NSLog(@"b is %d", b);
};

JuneBlock();
  • 注意點(diǎn)
  1. 調(diào)用 Block 之前,一定要做判斷
if(JuneBlock)
{
    JuneBlock();
}
  1. 在定義 Block 時(shí),有形參時(shí),寫上參數(shù)名稱,使用 Xcode 調(diào)此 Block 時(shí),會(huì)有提示,直接敲回車,快速創(chuàng)建形參代碼

Protocol 協(xié)議

  • 用來(lái)聲明一大堆方法(不能聲明成員變量和實(shí)現(xiàn))
  • 只要某個(gè)類遵守了這個(gè)協(xié)議,就能擁有這個(gè)協(xié)議中的所有方法聲明
  • 只要父類遵守了某個(gè)協(xié)議,就相當(dāng)于子類也遵守了
  • 協(xié)議可以定義在單獨(dú) .h 文件中,也可以定義在某個(gè)類中
    • 如果此協(xié)議只用在某個(gè)類中,就定義在某個(gè)類中
    • 如果此協(xié)議用在很多類中,就應(yīng)該定義在單獨(dú)文件中
  • 分類可以定義在單獨(dú).h.m中,也可以定義在原來(lái)類中
    • 一般情況下,都是定義在單獨(dú)文件
    • 定義在原來(lái)類中的分類,要能看懂語(yǔ)法
  • 協(xié)議遵守協(xié)議
    • 一個(gè)協(xié)議可以遵守其他多個(gè)協(xié)議,多個(gè)協(xié)議之間用逗號(hào),隔開(kāi)
    • 一個(gè)協(xié)議遵守了另外一個(gè)協(xié)議,就擁有了另一個(gè)協(xié)議的所有方法聲明
// 協(xié)議聲明
@protocol 協(xié)議名稱
// 方法聲明列表
@end

// 協(xié)議遵守協(xié)議
@protocol 協(xié)議名稱 <協(xié)議1, 協(xié)議2>
// 方法聲明列表
@end

// 某個(gè)類遵守協(xié)議,多個(gè)協(xié)議
@interface 類名 : 父類 <協(xié)議名,其他協(xié)議名,...>
@end 

// 定義了一個(gè)名叫 JuneProtocol 的協(xié)議
@protocol JuneProtocol <NSObject>
@end

// 某個(gè)類 .h 中使用協(xié)議
@protocol 協(xié)議名;

相當(dāng)于 @class,但是具體使用時(shí),要在 .m 文件中 #import"協(xié)議類名"
  • 關(guān)鍵字 : 用途在于程序員之間的交流

    • @required:要求實(shí)現(xiàn),不實(shí)現(xiàn)就會(huì)發(fā)出警告(不寫此關(guān)鍵字,默認(rèn)是要求)
    • @optional:不要求實(shí)現(xiàn)
  • 基協(xié)議 NSObject

    • NSObject 是一個(gè)基類,最根本最基本的類,任何其他類最終都要繼承它
    • 其實(shí)還有一個(gè)協(xié)議,名字也叫 NSObject,它是一個(gè) 基協(xié)議,最根本最基本的協(xié)議
    • NSObject 協(xié)議中聲明很多最基本的方法,比如 description、retain、release
    • 建議每個(gè)新的協(xié)議都要遵守 NSObject 基協(xié)議
@protocol JuneProtocol <NSObject>
@end
  • 定義一個(gè)變量的時(shí)候,限定這個(gè)變量保存的對(duì)象遵守某個(gè)協(xié)議
類名<協(xié)議名> *變量名
id<協(xié)議名> 變量名
NSObject<JuneProtocol> *obj
id<JuneProtocol> obj2
// 如果沒(méi)有遵守對(duì)應(yīng)的協(xié)議,編譯器會(huì)警告


// 要求 obj 保存的對(duì)象必須是遵守 JuneProtocol 這個(gè)協(xié)議
NSObject<JuneProtocol> *obj = [[NSObject alloc] init];

id<JuneProtocol> obj = [[NSObject alloc] init];

id 相當(dāng)于 NSObject*
  • @property中聲明的屬性也可以用作一個(gè)遵守協(xié)議的限制
@property (nonatomic, weak) 類名<協(xié)議名> *屬性名;
@property (nonatomic, weak) id<協(xié)議名> 屬性名;

@property (nonatomic, weak) Vampire<JuneProtocol> *p;
@property (nonatomic, weak) id<JuneProtocol> obj;

代理設(shè)計(jì)模式

@property (nonatomic, weak) id<協(xié)議名> delegate;

本類對(duì)象.delegate = 某個(gè)類對(duì)象 (必須遵守并實(shí)現(xiàn)了協(xié)議的類對(duì)象)
協(xié)議的命名格式:xxxDelegate
所有,以后定義代理時(shí),如下

// 定義了一個(gè)名叫 JuneDelegate 的協(xié)議
@protocol JuneDelegate <NSObject>
@optional
- (void)didSelectItemAtIndex:(NSUInteger)index withView:(JuneView *)juneView ;
@end

@interface JuneView : UIView
@property (nonatomic, weak) id<JuneDelegate> delegate;
@end

@implementation JuneView
- (void)clickItem:(UIButton *)item
{
    if ([_delegate respondsToSelector:@selector(didSelectItemAtIndex:withView:)]) {
        [_delegate didSelectItemAtIndex:item.tag withView:self ];
    }
}
@end

delegate為什么用weak或assign修飾,而不用strong修飾?

在ARC中,只要對(duì)象沒(méi)有強(qiáng)指針就會(huì)自動(dòng)釋放,防止循環(huán)引用。
詳細(xì)解釋

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,639評(píng)論 1 32
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,224評(píng)論 8 265
  • OC語(yǔ)言基礎(chǔ) 1.類與對(duì)象 類方法 OC的類方法只有2種:靜態(tài)方法和實(shí)例方法兩種 在OC中,只要方法聲明在@int...
    奇異果好補(bǔ)閱讀 4,517評(píng)論 0 11
  • 開(kāi)學(xué)啦!
    FHMing閱讀 151評(píng)論 0 0
  • 琴聲款款而來(lái), 輕聲喚侶伴, 一種期盼。 二胡相約來(lái)應(yīng)拍, 悠揚(yáng)婉轉(zhuǎn), 聲聲慢。 琴鍵莊重把口開(kāi), 郎的心意真不變...
    mjhjht閱讀 258評(píng)論 0 1

友情鏈接更多精彩內(nèi)容