日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios nslog 例子_iOS Block实例

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios nslog 例子_iOS Block实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

iOS之Block詳解:Block詳解

ViewController.h(ARC)

#import

@interface ViewController : UIViewController

// 屬性聲明的block都是全局的__NSGlobalBlock__

@property (nonatomic, copy) void (^copyBlock)();

@property (nonatomic, weak) void (^weakBlock)();

@end

ViewController.m(ARC)

#import "ViewController.h"

#import "Test.h"

typedef void (^blockSave)(void);

typedef void (^typedefBlock)(void);

void (^outFuncBlock)(void) = ^{

NSLog(@"someBlock");

};

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

NSLog(@"block : %@", ^{NSLog(@"block");}); // __NSGlobalBlock__

NSString *str3 = @"1234";

NSLog(@"block is %@", ^{NSLog(@":%@", str3);}); // __NSStackBlock__

#pragma mark - 當全局block引用了外部變量,ARC機制優化會將Global的block,轉為Malloc(堆)的block進行調用。

__block int age = 20;

int *ptr = &age;

// ARC下

blockSave x = ^{

NSLog(@"(++age):%d", ++age); // 變量前不加__block的情況下,會報錯,變量的值只能獲取,不能更改

};

blockSave y = [x copy];

y();

NSLog(@"x():%@, y():%@ , (*ptr):%d", x, y, *ptr);

// MRC下

Test *test = [[Test alloc] init];

[test test];

[test exampleB];

/**總結:

ARC下:(++age):21 (*ptr):20 // blockSave在堆中,*ptr在棧中

MRC下:(++age):21 (*ptr):21 // blockSave和*ptr都在棧中

*/

#pragma mark - copyBlock(未使用函數內變量) __NSGlobalBlock__

self.copyBlock = ^{

};

NSLog(@"1:%@", self.copyBlock);

#pragma mark - weakBlock(未使用函數內變量) __NSGlobalBlock__

self.weakBlock = ^{

};

NSLog(@"2:%@", self.weakBlock);

#pragma mark - copyBlock (使用函數內變量) __NSMallocBlock__

self.copyBlock = ^{

age = age+1-1;

};

NSLog(@"3:%@", self.copyBlock);

#pragma mark - weakBlock(使用函數內變量) __NSStackBlock__

self.weakBlock = ^{

age = age+1-1;

};

NSLog(@"4:%@", self.weakBlock);

#pragma mark - someBlock(定義在函數體外) __NSGlobalBlock__

NSLog(@"5:%@", outFuncBlock);

#pragma mark - typedefBlock(函數體外自定義的Block) __NSGlobalBlock__

typedefBlock b = ^{

};

NSLog(@"6:%@", b);

#pragma mark - 對棧中的block進行copy

// 不引用外部變量,定義在全局區、表達式沒有使用到外部變量時,生成的block都是__NSGlobalBlock__類型

void (^testBlock1)() = ^(){

};

NSLog(@"testBlock1: %@", testBlock1);

// 引用外部變量 -- ARC下默認對block進行了copy操作,所以這里是__NSMallocBlock__類型

void (^testBlock2)() = ^(){

age = age+1-1;

};

NSLog(@"testBlock2: %@", testBlock2);

// Blocks提供了將Block和__block變量從棧上復制到堆上的方法來解決變量作用域結束時銷毀的問題,堆上的Block會依然存在。

/*那么什么時候棧上的Block會復制到堆上呢?

1.調用Block的copy實例方法時

2.Block作為函數返回值返回時(作為參數則不會)

3.將Block賦值給附有__strong修飾符id類型的類或Block類型成員變量時

4.將方法名中含有usingBlock的Cocoa框架方法或GCD的API中傳遞Block時

在使用__block變量的Block從棧上復制到堆上時,__block變量也被從棧復制到堆上并被Block所持有。

*/

/*block里面使用self會造成循環引用嗎?

1.很顯然答案不都是,有些情況下是可以直接使用self的,比如調用系統的方法:

[UIView animateWithDuration:0.5 animations:^{

NSLog(@"%@", self);

}];

因為這個block存在于靜態方法中,雖然block對self強引用著,但是self卻不持有這個靜態方法,所以完全可以在block內部使用self。

2.當block不是self的屬性時,self并不持有這個block,所以也不存在循環引用

void(^block)(void) = ^() {

NSLog(@"%@", self);

};

block();

3.大部分GCD方法:

dispatch_async(dispatch_get_main_queue(), ^{

[self doSomething];

});

因為self并沒有對GCD的block進行持有,沒有形成循環引用。

4.……

只要我們抓住循環引用的本質,就不難理解這些東西。

*/

}

Test類在MRC條件下運行( -fno-objc-arc )

Test.h(MRC)

#import

@interface Test : NSObject

- (void)test;

@end

Test.m(MRC)

#import "Test.h"

@implementation Test

- (void)test

{

__block int age = 20;

int *ptr = &age;

void (^textBlock)() = ^{

NSLog(@"(++age):%d", ++age);

};

textBlock();

// 對block進行retain、release、copy,retainCount都不會變化,都為1

// [textBlock retain];

// [textBlock copy];

// [textBlock release];

NSLog(@"Test: textBlock:%@, (*ptr):%d, %lu", textBlock, *ptr, (unsigned long)[textBlock retainCount]);

/**

MRC下:(++age):21 (*ptr):21

*/

#pragma mark - 對棧中的block進行copy

// 不引用外部變量

/* 這里打印的是__NSGlobalBlock__類型,但是通過clang改寫的底層代碼指向的是棧區:impl.isa = &_NSConcreteStackBlock

這里引用巧神的一段話:由于 clang 改寫的具體實現方式和 LLVM 不太一樣,并且這里沒有開啟 ARC。所以這里我們看到 isa 指向的還是__NSStackBlock__。但在 LLVM 的實現中,開啟 ARC 時,block 應該是 __NSGlobalBlock__ 類型

*/

void (^testBlock1)() = ^(){

};

void (^testBlock2)() = [testBlock1 copy];

NSLog(@"Test: testBlock1: %@, testBlock2: %@", testBlock1, testBlock2);

[testBlock2 release];

// 引用外部變量,block為__NSStackBlock__類型

void (^testBlock3)() = ^(){

age = age+1-1;

};

void (^testBlock4)() = [testBlock3 copy];

NSLog(@"Test: testBlock3: %@, testBlock4: %@", testBlock3, testBlock4);

[testBlock4 release];

}

github地址:BlockTest

總結

以上是生活随笔為你收集整理的ios nslog 例子_iOS Block实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。