Block是對象。
如何判斷mrc,arc
1.delloc 能否調用super,能mrc,不能arc。
2.retain release能用mrc
ARC管理原則:只要一個對象沒有被強指針修飾就會被銷毀,默認局部變量都是強指針,存放到棧區里面
MRC小常識:1.沒有使用strong,weak,局部變量對象就是相當于基本數據類型
? ? ? ? ? ? ? ? ? ? ? ?2.MRC給屬性賦值,一定要用set方法,不能直接訪問下劃線成員屬性賦值。
在Block使用中,Block內部能夠讀取外部局部變量的值。但我們需要改變這個變量的值時,我們需要給它附加上__block修飾符。沒有用_block修飾的話,默認復制局部變量到block里,此時是更改局部變量值,并不能改變block內部的局部變量的值。而用_block修飾的話,會將局部變量的地址復制過去,所以更改局部變量,block會讀取到這個變化。
MRC:管理block:只要block中引用了外部局部變量,block就放在棧里面。如果block沒有引用外部局部變量,block放在全局區。block只能使用copy,不能使用retain。因為使用retain,block還是在棧里。用copy放在堆里。
ARC:管理block:只要block中引用了外部局部變量,block就放在堆里面。因為局部變量在arc是強指針。如果block沒有引用外部局部變量,block放在全局區。block聲明用strong修飾,最好不用copy修飾。copy的set方法會進行判斷。 block聲明用weak修飾,會被銷毀。
一。block 訪問外面變量規則:
》block 內部可以訪問外面的變量。
》默認情況下,block 內部不能修改外面的局部變量;但可以修改全局變量。
》給局部變量加上 __block 關鍵字,那么這個局部變量就可以在block 內部修改。
二。利用 typedef 定義block 類型:防止多次定義
》typedef int (^MyBlock)(int , int ) ;
// 以后就可以利用MyBlock這種類型來定義block變量。
MyBlock b1? ;
b1 = ^(int a , int b ){
return a - b ;
}? ;
MyBlock b2 = ^(int a , int? b) {
return a + b ;
} ;
Block幾大關鍵點:
1.保存代碼塊
void(^block)()=^{
NSLog(@"調用block");
};
Block變量的聲明格式為:?
返回值類型(^Block名字)(參數列表);
// 聲明一個無返回值,參數為兩個字符串對象,叫做
aBlock的Blockvoid(^aBlock)(NSString*x,NSString*y);
// 形參變量名稱可以省略,只留有變量類型即可
void(^aBlock)(NSString*,NSString*);
注: ^被稱作"脫字符"
Block變量的賦值
Block變量的賦值格式為:
?Block變量 = ^(參數列表){函數體};
aBlock = ^(NSString*x,NSString*y){
NSLog(@"%@ ---- %@", x, y);};
2.傳值
相比于代理,block傳值很簡潔
Block聲明:
@interfaceMViewController :UIViewController
@property(nonatomic,strong)void(^block1)(NSString*value);
@end
Block賦值
MViewController*vc = [[MViewControlleralloc]init];
vc.view.backgroundColor= [UIColorblueColor];
vc.block1= ^(NSString*value) {
NSLog(@"%@",value);
};
[self presentViewController:vcanimated:YEScompletion:nil];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{
if(_block1) {
_block1(@"123");
}
打印結果
3.block循環引用:
我引用你,你引用我。造成雙方都不會銷毀,造成內存泄漏。
__weak typeof(self) weakSelf =self;
如果在block要使用延時執行,加上
__weak typeof(weakSelf) strongSelf =weakSelf;
執行完block時在銷毀。
4.block變量傳遞
inta =3;
void(^block)()=^{
NSLog(@"%d",a);
};
a=5;
block();
輸出是3,因為值已經傳進去了。
static int a =3;
void(^block)()=^{
NSLog(@"%d",a);
};
a=5;
block();
輸出是5.
總結:如果是局部變量,block是值傳遞。如果是全局變量或者靜態變量,_block修飾的變量,是指針傳遞。
5.block當參數使用:
把block當參數使用,并不是馬上調用,而是方法決定。做什么事由外部決定,什么時候做由內部決定
#import
@interfaceCalculator :NSObject
@property(nonatomic,assign)NSIntegerresult;
- (void)calculator:(NSInteger(^)(NSInteger))calblock;
@end
#import"Calculator.h"
@implementationCalculator
- (void)calculator:(NSInteger(^)(NSInteger))calblock{
if(calblock) {
_result= calblock(_result);
}
}
Calculator*cal = [[Calculatoralloc]init];
[calcalculator:^(NSIntegerresult){
result +=10;
returnresult;
}];
NSLog(@"%ld",(long)cal.result);
6.block當返回值使用