- 值傳遞:基本數據類型的變量之間的數據傳遞
//值傳遞不會改變變量的值 void func(int a) { a = 4; } int main(int argc, const char * argv[]) { int a = 8 ; func(a); printf("%d",a);//答案為8 return 0; }
2. 指針類型之間的地址傳遞
//地址傳遞會改變變量的值 void func(int *a) { *a = 4; } int main(int argc, const char * argv[]) { int a = 8 ; func(&a); printf("%d",a);//答案為4 return 0; }
3. 全局變量static和extern
1)static修飾的全局變量作用范圍為定義變量的文件,變量存儲在靜態區,生命周期與程序生命一致;
2)extern只能聲明變量,使作用范圍擴大到整個程序文件,生命周期與程序生命一致;
4.代理設置模式的數據傳值
代理模式是為了解決程序的低耦合,高內聚而產生,比如:
1)A對象做不了的事情,B對象來幫A做;
2)B對象想監聽A對象的行為;
3)當A發生一些事情, 想通知B對象的時候
//A設計協議 @protocol testViewDelegate @optional -(void)outPut:(NSString *)theTitle; @end //B遵守協議
... //B實現協議方法
...
5. 通過系統通知傳值
//先發布通知 /* name:通知名稱 object:誰發出通知 nil代表匿名發布 */ [[NSNotificationCenter defaultCenter] postNotificationName:@"note" object:nil]; //監聽通知 //方式一: /* Observer:誰觀察通知 selector:監聽到通知,就會調用這個方法 name:通知名稱 object:誰發出通知nil代表監聽所有 */ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reciveNote) name:@"note" object:nil]; //方式二: /* name:通知名稱 object:誰發出通知 queue: 確定Block在哪個線程調用 隊列,傳入nil,block就會直接運行在發布通知線程中 usingBlock:只要監聽到通知,就會自動調用這個block */ _observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { NSLog(@"%@",self); NSLog(@"%@",[NSThread currentThread]); NSLog(@"調用了block:監聽到通知"); }];
//方式三
//userInfo表示傳入的數據
[[NSNotificationCenter defaultCenter] postNotificationName:@"note" object:nil userInfo:nil];
6.通過的block傳遞(此項重點頗多)
6.1 Block聲明
// 聲明:返回值(^block變量名)(參數) void(^block)();//(無返回值無參數)
6.2 Block定義
// 定義 // 方式一: void(^block1)() = ^(){ NSLog(@"調用block1"); }; // 調用Block,就會去查看下Block保存代碼 block1(); // 方式二:block如果沒有參數,可以省略() // void(^)() void(^block2)() = ^{ }; // 方式三:block定義中,返回值可以省略 // 類型:int(^)() int(^block3)() = ^int{ return 2; }; //在Xcode中的快捷鍵是inline
6.3 Block類型
6.3.1 是對象
6.4 Block作用
6.4.1 保存代碼塊
6.4.2 Block:在一個類中定義,在另一個類中調用(常用), -> 傳值
//在A類中定義一個block屬性 @property (nonatomic ,strong) void(^block)(); //在B類中賦值 // 打電話 CellItem *item = [[CellItem alloc] init]; item.title = @"打電話"; item.block = ^{ NSLog(@"打電話"); }; //在B類方法中使用 if (item.block) { item.block(); }
6.4.3 傳值:
A -> B 順傳:定義屬性
B -> A 逆傳:代理(block替換代理)
//為了替代代理 //在B類中聲明block屬性 @property (nonatomic ,strong) void(^valueBlock)(NSString *value); //同時在B類中使用,把值傳遞出去 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { if (_valueBlock) { _valueBlock(@"123"); } } //在A類中定義block(首先拿到B類就能拿到B類傳出去的值) ModalViewController *modalVc = [[ModalViewController alloc] init]; modalVc.valueBlock = ^(NSString *value){ NSLog(@"接收到%@",value); };
6.5 block的變量傳遞
6.5.1 默認局部變量在block中 是值傳遞
6.5.2 如果局部變量被static,__block,那么都是指針傳遞
6.5.3 全局變量.也是指針傳遞
6.6 block作為參數使用
// 計算 - (void)calculate:(int(^)(int))block; //實現方法(把值傳遞出去) - (void)calculate:(int (^)(int))block { _result = block(_result); } //在另一個類中定義 CalculateManager *mgr = [[CalculateManager alloc] init]; [mgr calculate:^(int result){ // 計算 result += 5; result *= 2; return result; }];
6.7 block做為方法的返回值
//聲明方法 - (CalculateManager *(^)(int))add; //實現方法(此方法可以實現鏈式點語法) - (CalculateManager *(^)(int))add { return ^(int value){ _result += value; return self; }; } CalculateManager *mgr = [[CalculateManager alloc] init]; mgr.add(5).add(5).add(5).add(5);
6.8 block內存管理:
非ARC環境:block怎么去管理內存
block沒有訪問外部局部變量,存放到全局區
block訪問外部局部變量,block存放棧里面
只要block訪問變量,是整個app都在的變量,那么肯定在全局區
在非ARC中.不能使用retain引用block,不會把放在堆里面,在非ARC中只能使用copy,才會把block放在堆里面
ARC環境:
block訪問外部局部變量,block存放堆里面
可以使用strong去引用
補充:內存五大區:堆,棧,方法區,全局區,常量區
堆:手動管理內存
棧:不需要手動管理內容,代碼塊一過,會自動清空棧里面內存
如何判斷非ARC環境:
1.重寫dealloc,調用super,ARC中不能調用[super dealloc]
2.判斷下是否可以調用retain,release等等
非ARC開發中注意:
1.訪問屬性,不要直接使用_,而是通過set,get方法去訪問
2.非ARC中沒有weak -> assign,strong -> retain
7 通過寫數據到沙盒保存數據,再取數據(NSUserDefaults)
8 單例
