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实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: otc是什么药(为什么同样是非处方药,还
- 下一篇: 工作占用了太多私人时间_下班后还要被逼谈