傳值 1 順向傳值 順傳 屬性傳值 運行方式為 A à B 原理: 在B頁面的控制器中,創建需要的屬性,由於控制器是由 A 跳到 B 的,因此可以在 A 中拿到 B 中的屬性,直接賦值.(賦值在控制器跳轉的時候完成) 在 B 中定義一個屬性 在 A 中拿到 B 的非私有屬性 在 A 中直接對 A 拿 ...
傳值
1 順向傳值
順傳 屬性傳值 運行方式為 A à B
原理: 在B頁面的控制器中,創建需要的屬性,由於控制器是由 A 跳到 B 的,因此可以在 A 中拿到 B 中的屬性,直接賦值.(賦值在控制器跳轉的時候完成)
- 在 B 中定義一個屬性
- 在 A 中拿到 B 的非私有屬性
- 在 A 中直接對 A 拿到的 B 的屬性賦值即可.
方法: - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
當我們拿到了segue也就拿到了他的屬性,就可以拿到目標控制器這個屬性,這時候也就相當於我們在A控制器里就拿到了B,也就可以給B設置數據了,這也就是所謂的順傳,主要是用到了這個方法。
2 逆向傳值
逆傳 包含三種方式 通知 代理 block(閉包)
>>> 通知:
1 什麼是通知?
通知是一種消息傳遞方式,可以傳遞消息信息.
2 通知的特點?
- 通知必須包含:通知發佈者,通知中心和通知的接受者.
- 通知的發佈者包含:通知的名稱,通知的發佈者以及通知要傳遞的信息.
- 通知中心只是用來轉發通知發佈者發佈的信息.
- 通知接收者又稱為監聽者:用來接收通知發送者發送的信息.
- 通知可以實現消息的一對多,一對一,多對一的傳遞方式.
- 通知可以實現越級傳遞,即通知消息的傳遞可以不受控制器層級數的限制傳遞信息.
3 通知使用註意事項:
- 通知使用的時候必須要先註冊通知監聽者,再發佈通知,否則將接收不到通知發佈的信息
- 通知使用完畢之後一定要在監聽者對象釋放前移除通知.
4 通知的使用步驟:
1> 在要發佈通知的地方 註冊併發布通知
[[NSNotificationCenter defaultCenter] postNotificationName:通知名 object:nil(通知的發佈者) userInfo:通知信息];
2> 在需要接收信息的地方註冊通知監聽者接收通知
[[NSNotificationCenter defaultCenter] addObserver:self(通知觀察者) selector:@selector(通知實現方法) name:@"通知名稱" object:nil(通知的發佈者)];
實現通知的方法.該方法實現要實現的操作
3> 移除通知監聽者
[[NSNotificationCenter defaultCenter]removeObserver:self];
>>> 代理:
1 什麼是代理?
當 B 想做一件事但是 B 做不了或者 B 想把做的事情通知給 A或者 A 想監聽 B的時候.
原理: B 要對 A 進行傳值(但是是 A 載入的 B),所以 B 要擁有已經創建的 B,所以 B 要有代理屬性指向 A,所以要在 B 中設置代理協議.
2 代理使用的註意事項?
- 代理使用的時候只能從一個控制器傳遞到上一個控制器,不能隔控制器傳遞
- 代理是一對一是使用
3 代理的使用步驟
1> 在 B.h 中
遵守協議
@protocol Vc2Delegate
設置代理方法
@optional
- (void)passValue:(NSString *)value;
@property(nonatomic,assign)id<Vc2Delegate>delegate;
2> 在 B.m 中
實現在 B.h 中聲明的方法
3> 在 A.m 中
設置自己為代理
遵守代理的協議
實現協議的方法
>>> block(閉包)
1> 什麼是 block?
Block 是一中數據類型.一個代碼塊.其存在的標記是 ^ 符號
原理:因為 B 要對 A 傳值,所以要在 B調用 block 的時候把值傳給 A.
2> Block 的一般形式
返回類型(^block名)(形參類型)=^(形參列表){代碼實現}
int(^sumBlock)(int,int) = ^(intX,intY){return X + Y}
使用的時候: block 名(實際參數)
一般使用 typedef 返回值類型 (^block名)(形參類型)
3> Block 使用特點
- 在 block 外部定義的變數在 block 內部是不能修改的,要想修改的時候,需要在外部定義的時候加上 __block
- 定義 block 的時候要使用 weak 修飾,避免產生迴圈使用.
- 在 block 內部應慎重使用 self.
4> 幾種 block 的區別
> stack block:當 block 被定義的時候會被分配到 stack(堆)中的一塊記憶體中.其特點是該 block 只能自己所聲明的區域中有效.該區的代碼塊運行結束的時候該代碼塊就被銷毀
> heap block:為解決上述問題,將block 代碼由 stack copy 到 heap 區域(在 block 代碼右側代碼塊後面加上 copy).在 stack中的 block 代碼塊,系統會在調用它之後自動清理它,而在 heap 中的 block,與其他變數類似,接受計數器的管理,只有當計數器為0的時候才被銷毀.
5> Block 的使用步驟
- 定義 block
- 在需要的地方調用並傳入實參
3 通知/代理/ block 三者之間的對比
3.1 通知
1> 特點: 可以”一對多”,”一對一”,”多對多”的傳值.
2> 使用步驟
> 發送通知
> 創建監聽者
> 接收通知
> 移除監聽者
3> 使用場景
> 多個控制器需要使用一個事件(通過通知的唯一通知名)
> 相隔多層的兩個控制器之間的跳轉.
4> 使用註意
> 在使用完將停止之後,一定要移除
> 通知接收的對象不好控制,因為只要調用一下該通知,並且通知名正確,就可以接收到該通知.
3.2 代理
> 特點:“一對一”,對於同一個協議,一個對象只能設置一個代理.所以單例對象不能使用代理.
> 代理更註重信息傳遞的過程,比如:信息什麼時候開始,什麼時候傳輸完成,數據傳輸的成功或者失敗.
> 代理的使用一般比較多,比較大的公司(百度等)常用代理實現.
3.3 block
> 特點:block 是一個代碼塊,它以閉包的形式將內容傳遞,基本上可以傳遞任何內容.block 是一個註重結果的傳輸(比如傳輸的成功/失敗)
> 閉包:能過讀取其他函數內部變數的函數.就是在一段請求連續代碼中可以看到調用參數和響應結果.因此使用 block 可以提高代碼的可讀性,擴展性和封裝性.
> block 的迴圈引用問題
ARC 下: __weak typeof(self) weakSelf = self;
MRC 下: __block typeof(self) weakSelf = self;
> 它的最大特點就是回調,回調的意思簡單的理解就是,將方法的聲明、調用與方法實現分開,將實現部分寫在需要傳值的控制器中(即聲明和調用在 B 中, 實現在 A中)。而且回調時可以傳入參數, block本身可以封裝一段代碼,因此在定義實現時,可以在實現部分寫入需要執行的代碼。可以說block簡化了代理方法,使用起來更靈活、簡便。通常用作方法的參數,在方法中進行回調。