通知、block,通知block
===================================
通知
===================================
一.通知(NSNotification)
// NSNotification 通知類,這個類中有 NSNotificationCenter 通知中樞類
NSNotificationCenter* notification = [NSNotificationCenter defaultCenter];
// 添加了一個監聽事件,其中,run1 則是觸發的事件方法,@“run”是通知的名字
[notification addObserver:self selector: @selector(run1) name: @"run" object:nil];
// 多次調用發送通知的方法,會觸發多次相應的回應程式法(run1)
[notification postNotificationName: @"run" object:nil];
// 刪除通知,如果想刪除通知,就可以調用removeObserver這個方法
[notification removeObserver:self name:@"run" object:nil];
【注】通知用的時候要添加通知,不用的時候一定要刪除通知,因為如果不刪除,這個通知一直存在
二.【代理和通知對比】
// 代理:小明->小剛->小紅->小李;結果:小李->小紅->小剛->小明
// 通知:小明註冊了通知;結果:小剛、小紅、小李都可以給小明發送訊息;
三.通知的注意事項
+ (void)test
{
xiaoming *xm = [[xiaoming alloc]init];
[xm test1];
//【注】不可以在類方法中添加監聽方法,這樣會導致程式崩潰
// NSNotificationCenter* notification = [NSNotificationCenter defaultCenter];
// [notification addObserver:self selector:@selector(run) name:@"run" object:nil];
//
// [xiaogang xgTest];
}
- (void)test1
{
NSNotificationCenter* notification = [NSNotificationCenter defaultCenter];
[notification addObserver:self selector: @selector(run) name: @"run" object:nil];
//【注】添加監聽事件多次,發送訊息時會觸發多次run方法
[notification addObserver:self selector: @selector(run) name: @"run" object:nil];
[notification addObserver:self selector: @selector(run) name: @"run" object:nil];
[notification addObserver:self selector: @selector(run) name: @"run" object:nil];
//【注】刪除監聽,會刪除所有對應的name的監聽
// [notification removeObserver:self name: @"run" object:nil];
//【注】刪除監聽,會刪除所有對應的name的監聽,object後面的參數應根據addObserver方法中的參數來
[notification removeObserver:self name: @"run" object: @""];
[notification addObserver:self selector: @selector(run) name: @"run" object:nil];
[xiaogang xgTest];
}
===================================
block
===================================
一.認識block
block又稱為代碼塊,它是^符號開頭的方法;一般用於多線程、網路通訊。蘋果公司從ios4開始主推block文法
block實體形式如下:
^(傳入的參數列表){行為主體(具體的代碼實現)}
// c語言中聲明了一個指標函數
void (* cFunc)(void);
// oc中block 跟指標函數很像
// 寫了一個block變數ocFunc
void(^ ocFunc)(void);
1.不帶參數的block
//【注】block文法,先執行{}外面的文法,只有調用block函數的時候,才會執行內部
// 實現了一個block函數
// ^(傳入的參數列表){行為主體(具體的代碼實現)}
//【注】block函數是以;結尾
ocFunc=^(void)
{
NSLog(@"in blocks");
};
NSLog(@"befor blocks");
// block函數的調用
ocFunc();
NSLog(@"after blocks");
2.帶參數的block
// int 傳回值類型;myblock1 block函數名稱; int a,int b是形參; ^(int a,int b){};是行為主體
int (^ myblock1)(int a,int b)=^(int a,int b)
{
return a+b;
};
// block函數的調用
int result1 = myblock1(10,20);
NSLog(@"result1 = %d",result1);
// 一個函數中無法包含另外一個函數,block應運而生了
func(10,20);
int b = 8;
int (^myblock2)(int a) = ^(int a)
{
return b+a;
};
int result2 = myblock2(5);
NSLog(@"rusult2 = %d",result2);
myBlock myblock3 = ^(int a,int b)
{
return a+b;
};
int result3 = myblock3(90,8);
NSLog(@"rusult3 = %d",result3);
//【注】如果要在block內部對外部變數進行修改,則外部變數需要加__block修飾符(有2條底線)
__block int sum;
void(^myblock4)(int a,int b) = ^(int a,int b)
{
sum = a +b;
};
myblock4(4,5);
NSLog(@"sum = %d",sum);
// A這個值會copy一份,block內部的操作是copy的這一部分,所以,外部無論如何對這個A進行修改,block內部都是不變的
int A = 8;
int(^myblock5)(int ) = ^(int a)
{
return A + a;
};
A = 5;
int result4 = myblock5(3);
NSLog(@"result4 = %d",result4);
//【注】需要注意的是,這裡copy的值是一個變數的值,如果是一個記憶體的位置(地址),也就說,就是這個變數的指標的話,它的值在block內部會被改變
NSMutableArray* array = [[NSMutableArray alloc]initWithObjects:@"one",@"two",@"three", nil];
void(^myblock6)(void) = ^(void)
{
[array removeLastObject];
};
// 在第0個位置插入字串@“0”;
[array insertObject:@"0" atIndex:0];
myblock6();
NSLog(@"array = %@",array);
// 對sum進行賦值,發現sum值被修改了
void(^myblock7)(void) = ^(void)
{
sum = 6;
};
myblock7();
NSLog(@"sum = %d",sum);
// static int B = 8;
// int (^myblock8)(int) = ^ (int a)
// {
// return B+a;
// };
// B = 5;
// int result5 = myblock8(3);
// NSLog(@"result5 = %d",result5);
static int B = 8;
int (^myblock8)(int) = ^ (int a)
{
B = 5;
return B+a;
};
int result5 = myblock8(3);
NSLog(@"result5 = %d",result5);
// [注]如果想把一個變數參與到block中運算修改,加一個static修飾符即可