久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

[iOS]Block技術(shù)中的weak-strong

 沒原創(chuàng)_去搜索 2015-10-09

本篇文章的主要內(nèi)容

  • 了解何謂block,。
  • 了解block的使用方法。

     Block 是iOS在4.0版本之后新增的程序語法.
    
     在iOS SDK 4.0之后,,Block幾乎出現(xiàn)在所有新版的API之中,,換句話說,如果不了解Block這個(gè)概念就無法使用SDK 4.0版本以后的新功能,,因此雖然Block本身的語法有點(diǎn)難度,,但為了使用iOS的新功能我們還是得硬著頭皮去了解這個(gè)新的程序概念。

一,、看一看什么是Block

我們使用^運(yùn)算符來聲明一個(gè)Block變量,,而且在聲明完一個(gè)Block變量后要像聲明普通變量一樣,最后要加;,。

  • 聲明Block變量
    接下來,,我們通過一個(gè)例子來聲明一個(gè)簡單的Block變量.

    int (^block)( int ) = NULL;

    我們一起來看一下聲明Block變量的語法

    數(shù)據(jù)返回值類型  (^變量名) (參數(shù)列表) = NULL;
  • 賦值Block變量

    block = ^(int m){
     return m * m; 
    };
  • 使用Block變量
    //通過使用block變量,計(jì)算整型常量10的平方,并且打印在控制器輸出
    NSLog(@"10的平方是:%d",block(10));

注意,到目前我們應(yīng)該有發(fā)現(xiàn)block變量的使用步驟,,有類似于函數(shù)的步驟

  • 首先都要聲明(聲明函數(shù),聲明block變量);
  • 然后都要進(jìn)行實(shí)現(xiàn)(實(shí)現(xiàn)函數(shù),,為block變量賦值實(shí)現(xiàn)過程);
  • 最后都要進(jìn)行調(diào)用才能實(shí)現(xiàn)具體功能

二、看一看如何直接使用block參數(shù)

  • 數(shù)組排序

      //聲明數(shù)組變量
      NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:@"5",@"2",@"3",@"9",@"7", nil];
    
      //直接使用block進(jìn)行數(shù)組升序排序
      [mutableArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
          //將兩個(gè)參數(shù)轉(zhuǎn)換為字符串的對象
          NSString *value1 = (NSString *)obj1;
          NSString *value2 = (NSString *)obj2;
    
          //value1與value2兩個(gè)對象的比較結(jié)果直接返回
          return [value1 compare:value2];
      }];
    
      //打印可變數(shù)組變量
      NSLog(@"%@",mutableArray);
  • 簡單的網(wǎng)絡(luò)異步請求

      //聲明網(wǎng)絡(luò)地址對象
      NSURL *url = [NSURL URLWithString:@"http://www.qq.com"];
    
      //根據(jù)網(wǎng)絡(luò)地址對象,聲明網(wǎng)絡(luò)請求對象
      NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
      //直接使用block變量完成鏈接成功后的數(shù)據(jù)返回功能
      [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
          //將二進(jìn)制數(shù)據(jù)使用utf8編碼轉(zhuǎn)換成字符串對象
          NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
          //打印鏈接完成后的結(jié)果
          NSLog(@"%@",result);
    
      }];

      可以看出ios平臺中的很多功能都已經(jīng)集成了Block語法的處理方法.

三,、看一看深入理解Block語法

在本節(jié),,主要要去介紹的就是使用__block修飾的變量能夠完成的作用。

先來看一個(gè)例子,。

    //聲明一個(gè)局部整型變量
    int intValue = 3;

    //聲明一個(gè)返回值為int,一個(gè)int參數(shù)的block變量
    int (^block)(int) = ^(int m){
        return m * intValue;
    };

    //調(diào)用block變量,5作為參數(shù)之后的結(jié)果
    NSLog(@"block(5) = %d",block(5));

在上面的例子中,我們將intValue變量稱為block執(zhí)行過程中的外部變量,在block執(zhí)行過程中可以直接使用該外部變量,。

再看一個(gè)例子?!?/p>

    //聲明一個(gè)局部整型變量
    int intValue = 3;

    //聲明一個(gè)返回值為int,一個(gè)int參數(shù)的block變量
    int (^block)(int) = ^(int m){
        intValue++;
        return m * intValue;
    };

    //調(diào)用block變量,5作為參數(shù)之后的結(jié)果
    NSLog(@"block(5) = %d",block(5));

在上面的例子中,我們編譯程序后發(fā)現(xiàn)編譯器會有紅色錯(cuò)誤,錯(cuò)誤提示為
Variable is not assignable (missing __block type specifier)

為什么會出現(xiàn)不能被賦值的錯(cuò)誤提示呢,?
  • block在實(shí)現(xiàn)時(shí)就會對它引用到的它所在方法中定義的棧變量進(jìn)行一次只讀拷貝
  • 在 block 塊內(nèi)使用該只讀拷貝。

那為了避免上述錯(cuò)誤,,就要使用__block修飾符來修飾外部變量,用來通知編譯器該外部變量intValueblock中的intValue指的是同一塊兒內(nèi)存地址,,而不需要內(nèi)存拷貝。
<br/>
如下例:

    //將intValue局部整型變量使用__block修飾符進(jìn)行修飾
    __block int intValue = 3;

    //聲明一個(gè)返回值為int,一個(gè)int參數(shù)的block變量
    int (^block)(int) = ^(int m){
        intValue++;
        return m * intValue;
    };

    //調(diào)用block變量,5作為參數(shù)之后的結(jié)果
    NSLog(@"block(5) = %d",block(5));

四,、使用Block要注意的內(nèi)存問題

使用weak–strong dance技術(shù)來避免循環(huán)引用

舉例如下

//
//  ViewController.m
//
//  Created by lewis.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
{
    id observer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //添加觀察者,觀察主題修改消息通知,并且在收到消息通知后,打印視圖控制器對象
    observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"kThemeChangeNotification" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        NSLog(@"%@",self);
    }];
}

//當(dāng)視圖控制器對象銷毀時(shí),移除觀察者
- (void)dealloc
{
    if (observer) {
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }
}
@end

在上面代碼中,,我們添加向通知中心注冊了一個(gè)觀察者,,然后在 dealloc 時(shí)解除該注冊,,一切看起來正常。但這里有兩個(gè)問題:
在消息通知 block 中引用到了 self,,在這里 self 對象被 block 保留一次,而 observer 又 retain 該 block的一份拷貝,,通知中心又持有 observer,。因此只要 observer對象還沒有被解除注冊,block 就會一直被通知中心持有,,從而 self 就不會被釋放,,其 dealloc 就不會被調(diào)用。而我們卻又期望在 dealloc 中通過 removeObserver 來解除注冊以消除通知中心對 observer/block 的 保留次數(shù),。
同時(shí),,observer 是在 self 所在類中定義賦值,因此是被 self retain 的,,這樣就形成了循環(huán)引用,。
解決方式如下.

//
//  ViewController.m
//
//  Created by lewis.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
{
    id observer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //先聲明一個(gè)weak弱對象
    __weak ViewController *wSelf = self;

    //添加觀察者,觀察主題修改消息通知,并且在收到消息通知后,打印視圖控制器對象
    observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"kThemeChangeNotification" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note){

        //在block的執(zhí)行過程中,使用強(qiáng)對象對弱對象進(jìn)行引用
        ViewController *bSelf = wSelf;
        if (bSelf) {
            NSLog(@"%@",bSelf);
        }
    }];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//當(dāng)視圖控制器對象銷毀時(shí),移除觀察者
- (void)dealloc
{
    if (observer) {
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }
}

@end
  • 在 block 之前定義對 self 的一個(gè)弱引用 wSelf,因?yàn)槭侨跻?,所以?dāng) self 被釋放時(shí) wSelf 會變?yōu)?code style="padding: 2px 4px; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; color: rgb(101, 123, 131); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: rgb(253, 246, 227); border: none; white-space: pre;">nil,;
  • 在 block 中引用該弱應(yīng)用,考慮到多線程情況,,通過使用強(qiáng)引用 bSelf 來引用該弱引用,,這時(shí)如果 self 不為 nil 就會 retain self,以防止在后面的使用過程中 self 被釋放;
  • 在之后的 block 塊中使用該強(qiáng)引用 bself,,注意在使用前要對 bSelf 進(jìn)行了 nil檢測,,因?yàn)槎嗑€程環(huán)境下在用弱引用 wSelf 對強(qiáng)引用 bSelf 賦值時(shí),弱引用 wSelf可能已經(jīng)為 nil 了,。

      通過這種weak-strong手法,,block 就不會持有 self 的引用,從而打破了循環(huán)引用,。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多