讀古今文學網 > iOS編程基礎:Swift、Xcode和Cocoa入門指南 > 第13章 對像間通信 >

第13章 對像間通信

隨著應用中的對象變得越來越多,如何在對像間進行消息的發送或數據的通信就成為擺在我們面前的一個問題,這本質上還是一個架構問題。需要對代碼的構建做些規劃,使得代碼能夠各司其職,並且能在恰當的時刻根據需要共享信息。本章將會介紹一些系統性的思考方法,幫助你實現對像間的通信。

通信的問題常常可以歸結為一個對像要能看到另一個對像:對像Manny要能找到對像Jack,這樣才能夠向Jack發送消息。

一個顯而易見的解決辦法就是將Jack作為Manny的一個實例屬性值。這在Manny與Jack共享某些職責或彼此互為補充的情況下尤為有用。應用對象及其委託、表視圖及其數據源、視圖控制器及其所控制的視圖,在這些情況中,前者都有一個指向了後者的實例屬性。

這並不是說由於內存管理策略的問題(參見第12章),Manny需要聲明為Jack的所有者,不過它是可以這麼做的。對像不一定要保持其委託或數據源;與之類似,實現了目標-動作模式的對象(如UIControl)並沒有保持其目標。通過使用弱引用以及將屬性類型聲明為Optional,然後以前後一致且安全的方式來對待這個Optional,Manny可以在不擁有Jack的情況下,讓其假定對Jack的引用最終變為nil。另外,如果沒有可控制的視圖,那麼視圖控制器就是毫無意義的;當它有了視圖後,它會保持這個視圖,只有當視圖控制器自身銷毀時,它才會釋放這個視圖。

對象可以在沒有彼此引用的情況下進行雙向通信。其中一個對像擁有對另一個對象的引用就足夠了,因為前者(作為向後者發送的消息的一部分)可以包含對自身的引用。

比如,Manny可能會向Jack發送消息,其中一個參數就是對Manny的引用;這僅僅構成了一種身份證明形式,或一種邀請形式,表示Jack自己的方法完成處理後,如果還需要進一步的信息,那麼他可以向Manny發回消息。這樣,Manny可以令自身對Jack處於暫時可見的狀態;Jack不應該保持Manny(因為這顯然會導致保持循環的風險)。另外,這還是一種常見的模式。委託消息textFieldShouldBeginEditing:的參數是個對發送消息的UITextField的引用。目標-動作消息的第1個參數就是個對發送消息的控件的引用。

不過,Manny一開始是如何獲得對Jack的引用的呢?這是個重要的問題。iOS編程與面向對像編程的很重要的一個話題就是一個對像如何獲得其他對象的引用。情況紛繁複雜,需要具體問題具體分析,不過還是存在著一些通用模式,本章就將介紹這些模式。

Manny可以通過一些方式向Jack發送消息,同時又不必直接發送給Jack,可能他都不知道或不關心誰是Jack。通知與KVO就是這樣的,本章也將對其進行介紹。

最後,13.4節還將介紹這樣一個問題:在典型的iOS程序中,什麼樣的對象需要彼此能夠看到對方。