時(shí)間一長(zhǎng),尤其是在迭代或者維護(hù)一個(gè)框架成熟的應(yīng)用的時(shí)候酒奶,很多基礎(chǔ)的東西就會(huì)忘記蚁孔。今天寫了個(gè)帶有block的方法,竟然用了老長(zhǎng)時(shí)間惋嚎「芮猓看來(lái)要總結(jié)一下,忘記的時(shí)候有個(gè)地方另伍,可以翻一翻鼻百,看一看。
傳值方式都有啥
- 屬性傳值
- 委托Delegate傳值
- 通知NSNotification傳值
- block傳值
- 單例傳值
- runtime動(dòng)態(tài)綁定傳值
-----------------------看漲圖,放松下-----------------------
說(shuō)到人生摆尝,不管誰(shuí)都是業(yè)余新手啊温艇。 任何人都是第一次參加,人生這種事沒(méi)有什么專業(yè)老手堕汞。 by 伊坂幸太郎
1.屬性傳值
ViewController1頁(yè)面跳轉(zhuǎn)到ViewController2頁(yè)面【包括push中贝,或者模態(tài)跳轉(zhuǎn)】
- ViewController2的屬性
#import <UIKit/UIKit.h>
@interface ViewController2 : UIViewController
@property (nonatomic, strong)NSString *titleStr;
@end
- 如何傳值,在ViewController1跳轉(zhuǎn)的地方臼朗,以下代碼
ViewController2 *viewVc2 = [[ViewController2 alloc] init];
viewVc2.titleStr = @"傳給界面2的值";
[self presentViewController:viewVc2 animated:YES completion:^{
}];
2.委托Delegate傳值
這種方法的使用情景不同于上面的正向傳值邻寿,相反,當(dāng)ViewController2消失的時(shí)候视哑,它需要傳值給ViewController1
寫代理的步驟
- 聲明ViewController2的協(xié)議--protocol绣否,以及協(xié)議方法
- 在ViewController2的.h文件中聲明ViewController2的代理
- 在ViewController2要進(jìn)行傳值的地方,進(jìn)行容錯(cuò)處理挡毅,即判斷他的代理是否實(shí)現(xiàn)了自己的協(xié)議方法蒜撮,若完成,就執(zhí)行跪呈,進(jìn)行傳值段磨。
*在ViewController2的代理--ViewController1中,首先遵守ViewController2的協(xié)議耗绿,其次苹支,實(shí)現(xiàn)ViewController2的協(xié)議方法 - 上面的都完成了,就可以進(jìn)行傳值误阻。
注意不按這個(gè)套路出牌的债蜜,往往要吃很多虧晴埂。
慢慢長(zhǎng)大了,卻越來(lái)越覺(jué)得寻定,這個(gè)世界到處都他媽的套路儒洛。
到底是我不懂這個(gè)世界,還是世界拋棄了我@撬佟@哦汀!向胡!
我要回村里
下面的例子-----在ViewController2關(guān)閉的時(shí)候恼蓬,改變ViewController1的背景顏色
- 聲明ViewController2的協(xié)議--protocol,以及協(xié)議方法,并且聲明代理
#import <UIKit/UIKit.h>
@protocol ViewController2Delegate <NSObject>
- (void)setViewController1BackColor:(UIColor *)color;
@end
@interface ViewController2 : UIViewController
@property (nonatomic, assign)id <ViewController2Delegate>delegate1;
@end
- 在ViewController2要進(jìn)行傳值的地方捷枯,進(jìn)行容錯(cuò)處理,即判斷他的代理是否實(shí)現(xiàn)了自己的協(xié)議方法专执,若完成淮捆,就執(zhí)行,進(jìn)行傳值本股。
#import "ViewController2.h"
@interface ViewController2 ()
@end
@implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
close.backgroundColor = [UIColor purpleColor];
[self.view addSubview:close];
[close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
// Do any additional setup after loading the view.
}
- (void)closeClick {
if ([self.delegate1 respondsToSelector:@selector(setViewController1BackColor:)]) {
[self.delegate1 setViewController1BackColor:[UIColor redColor]];
}
[self dismissViewControllerAnimated:YES completion:^{
}];
}
- 在ViewController2的代理--ViewController1中攀痊,首先遵守ViewController2的協(xié)議,其次拄显,實(shí)現(xiàn)ViewController2的協(xié)議方法
#import "ViewController.h"
#import "ViewController2.h"
@interface ViewController ()<ViewController2Delegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
btn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}
- (void)test {
[self push];
}
- (void)push {
ViewController2 *viewVc2 = [[ViewController2 alloc] init];
viewVc2.titleStr = @"傳給界面2的值";
viewVc2.delegate1 = self;
[self presentViewController:viewVc2 animated:YES completion:^{
}];
}
- (void)setViewController1BackColor:(UIColor *)color {
self.view.backgroundColor = color;
}
@end
效果圖如下
苟径??躬审?棘街??承边?遭殉??博助?险污??富岳?蛔糯??窖式?蚁飒??萝喘?飒箭?狼电??弦蹂?肩碟??凸椿?削祈??脑漫?髓抑??优幸?
吨拍??网杆?羹饰??碳却?队秩??昼浦?馍资??关噪?鸟蟹??使兔?戏锹??火诸?锦针??置蜀?奈搜??盯荤?馋吗??秋秤?宏粤?脚翘??绍哎?
@property (nonatomic, assign)id <ViewController2Delegate>delegate1;
這兒為什么用assign来农??崇堰?沃于??拜讀一下下面文章海诲,我也是這意思繁莹,哈哈
[點(diǎn)這兒] http://www.reibang.com/p/398472616435
3.通知NSNotification傳值
在ViewController1中,注冊(cè)觀察者,并在dealloc中特幔,移除
#import "ViewController.h"
#import "ViewController2.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationClick:) name:@"setViewController1BackColor" object:nil];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
btn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}
- (void)notificationClick:(NSNotification *)noti {
NSDictionary *dic = noti.userInfo;
self.view.backgroundColor = (UIColor *)dic[@"color"];
}
- (void)test {
[self push];
}
- (void)push {
ViewController2 *viewVc2 = [[ViewController2 alloc] init];
viewVc2.titleStr = @"傳給界面2的值";
[self presentViewController:viewVc2 animated:YES completion:^{
}];
}
- (void)setViewController1BackColor:(UIColor *)color {
self.view.backgroundColor = color;
}
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:self];
}
@end
在ViewController2中咨演,點(diǎn)擊close按鈕,發(fā)送通知
#import "ViewController2.h"
@interface ViewController2 ()
@end
@implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
close.backgroundColor = [UIColor purpleColor];
[self.view addSubview:close];
[close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
// Do any additional setup after loading the view.
}
- (void)closeClick {
[[NSNotificationCenter defaultCenter] postNotificationName:@"setViewController1BackColor" object:self userInfo:@{@"color":[UIColor redColor]}];
[self dismissViewControllerAnimated:YES completion:^{
}];
}
- (void)viewWillDisappear:(BOOL)animated {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
效果圖---與上邊一樣
4.block傳值
block傳值是通過(guò)block塊進(jìn)行
在ViewController2中定義block屬性
// ViewController2.h
// JRMBubbleTutorial
//
// Created by 周欽凱 on 16/11/1.
// Copyright ? 2016年 Caroline Harrison. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef void(^setViewController) (UIColor *color);
@interface ViewController2 : UIViewController
@property (nonatomic, strong)NSString *titleStr;
@property (nonatomic, copy)setViewController block;
@end
在ViewController2.m中利用block聲明部分傳值
#import "ViewController2.h"
@interface ViewController2 ()
@end
@implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
close.backgroundColor = [UIColor purpleColor];
[self.view addSubview:close];
[close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
// Do any additional setup after loading the view.
}
- (void)closeClick {
_block([UIColor redColor]);
[self dismissViewControllerAnimated:YES completion:^{
}];
}
在ViewController中蚯斯,初始化ViewController2對(duì)象部分薄风,實(shí)現(xiàn)屬性block的實(shí)現(xiàn)部分,在代碼塊中實(shí)現(xiàn)改變ViewController1背景顏色的效果
#import "ViewController.h"
#import "ViewController2.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
btn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}
- (void)test {
[self push];
}
- (void)push {
ViewController2 *viewVc2 = [[ViewController2 alloc] init];
viewVc2.titleStr = @"傳給界面2的值";
viewVc2.block = ^(UIColor *color) {
self.view.backgroundColor = [UIColor redColor];
};
[self presentViewController:viewVc2 animated:YES completion:^{
}];
}
- (void)setViewController1BackColor:(UIColor *)color {
self.view.backgroundColor = color;
}
效果圖依然如上
問(wèn)題溉跃,block為什么用copy修飾
block本身是像對(duì)象一樣可以retain村刨,和release告抄。但是撰茎,block在創(chuàng)建的時(shí)候,它的內(nèi)存是分配在棧(stack)上打洼,而不是在堆(heap)上龄糊。他本身的作于域是屬于創(chuàng)建時(shí)候的作用域,一旦在創(chuàng)建時(shí)候的作用域外面調(diào)用block將導(dǎo)致程序崩潰募疮。 使用retain也可以炫惩,但是block的retain行為默認(rèn)是用copy的行為實(shí)現(xiàn)的,因?yàn)閎lock變量默認(rèn)是聲明為棧變量的阿浓,為了能夠在block的聲明域外使用他嚷,所以要把block拷貝(copy)到堆,所以說(shuō)為了block屬性聲明和實(shí)際的操作一致芭毙,最好聲明為copy筋蓖。
[詳情](http://www.cnblogs.com/MasterPeng/p/5311911.html)
目過(guò)代碼過(guò)千行,擼碼如有神 -- °腐
5.單例傳值
什么是單例退敦?粘咖?
單例模式是一種常用的軟件設(shè)計(jì)模式。在它的核心結(jié)構(gòu)中只包含一個(gè)被稱為單例的特殊類侈百。通過(guò)單例模式可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例而且該實(shí)例易于外界訪問(wèn)瓮下,從而方便對(duì)實(shí)例個(gè)數(shù)的控制并節(jié)約系統(tǒng)資源翰铡。如果希望在系統(tǒng)中某個(gè)類的對(duì)象只能存在一個(gè),單例模式是最好的解決方案讽坏。
1锭魔、書寫步驟
1)、創(chuàng)建類方法震缭,返回對(duì)象實(shí)例.以shared default current開頭赂毯。2)、創(chuàng)建一個(gè)全局變量用來(lái)保存對(duì)象的引用3)拣宰、判斷對(duì)象是否存在党涕,若不存在,創(chuàng)建對(duì)象
[點(diǎn)擊] http://www.reibang.com/p/2bdec6f7ebe7
上面單例巡社,為我們?cè)谌こ烫诺蹋峁┝艘粋€(gè)公共的對(duì)象,隨時(shí)隨地可以取到晌该,可以算為一種傳值方式肥荔。如果覺(jué)得不是,那看下面這個(gè)系統(tǒng)單例朝群。
- 存數(shù)據(jù)--- 全局
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"1" forKey:@"isAl"];
[userDefaults synchronize];
- 取數(shù)據(jù)--全局
[userDefaults objectForKey:@"isAl"];
5.runtime傳值
有時(shí)候燕耿,在同一個(gè)類里,方法之間傳值姜胖,我們可以采用runtime動(dòng)態(tài)綁定的方法
動(dòng)態(tài)綁定
// 第一個(gè)參數(shù):給哪個(gè)對(duì)象添加關(guān)聯(lián)
// 第二個(gè)參數(shù):關(guān)聯(lián)的key誉帅,通過(guò)這個(gè)key獲取
// 第三個(gè)參數(shù):關(guān)聯(lián)的value
// 第四個(gè)參數(shù):關(guān)聯(lián)的策略
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
動(dòng)態(tài)取值
objc_getAssociatedObject(self, key);
差不多了!S依场蚜锨!