iOS開發(fā)中的NSUndoManager的undo/redo功能(一顆后悔藥)

前言:以前保存賬戶登錄數(shù)據(jù)時(shí)用過一次CoreData,最近在研究CoreData官方demo(CoreDataBooks)的時(shí)候,發(fā)現(xiàn)了一個(gè)有意思的功能undo/redo,也就是給我們彌補(bǔ)犯下犯錯(cuò)的功能,去年在公司做個(gè)一個(gè)收銀臺(tái)的功能凉逛,到現(xiàn)在還記得在深入三層選擇支付方式(紅包兔簇,銀行卡峦筒,余額的排列組合)時(shí)陵且,用戶操作產(chǎn)生的臨時(shí)數(shù)據(jù)到底在什么時(shí)候和model中的數(shù)據(jù)同步而糾結(jié)的事货葬。隱隱的覺得這個(gè)撤消/重做功能可以優(yōu)雅的解決那個(gè)讓我耿耿于懷的問題垢粮,于是今天先"膚淺"的學(xué)習(xí)一下贴届。

一、簡介

幫助文檔上說蜡吧,NSUndoManager就是一個(gè)通用的撤消堆棧粱腻,你可以注冊一個(gè)回調(diào)函數(shù),當(dāng)對象的屬性改變時(shí)斩跌,你可以通過調(diào)用該函數(shù)绍些,進(jìn)行撤消管理∫唬可以看到NSUndoManager中有兩個(gè)id類型的成員變量(private) _undoStack柬批,和_redoStack,兩個(gè)stack初始化時(shí)都是空的袖订,里面可以存放NSInvocation類型的數(shù)據(jù)氮帐,NSInvocation中大致有methodSignature,argumentsRetained洛姑,target上沐,selector這些屬性。它封裝了消息事件的一些信息楞艾。最關(guān)鍵的大概就是這幾句話:initially, both stacks are empty. Recording undo operations adds to the undo stack, but the redo stack remains empty until undo is performed. Performing undo causes the reverting operations in the latest group to be applied to their objects. Since these operations cause changes to the objects’ states, the objects presumably register new operations with the undo manager, this time in the reverse direction from the original operations. Since the undo manager is in the process of performing undo, it records these operations as redo operations on the redo stack. Consecutive undos add to the redo stack. Subsequent redo operations pull the operations off the redo stack, apply them to the objects, and push them back onto the undo stack.大概意思就是参咙,當(dāng)進(jìn)行一次操作時(shí)龄广,undo operations記錄著與當(dāng)前操作相反信息的NSInvocation壓入到_undoStack中,當(dāng)進(jìn)行undo operations時(shí)蕴侧,_undoStack的棧頂元素出棧择同,記錄著與棧頂元素的反相操作的NSInvocation壓入到_redoStack中(這時(shí)NSInvocation中的信息是與原操作一樣的,負(fù)負(fù)得正的原理)净宵。

三敲才、簡單的實(shí)現(xiàn)

系統(tǒng)提供了- (void)registerUndoWithTarget:(id)target selector:(SEL)selector object:(nullable id)anObject、- (id)prepareWithInvocationTarget:(id)target择葡,- (void)registerUndoWithTarget:(id)target handler:(void (^)(id target))undoHandler最后一種是iOS9新加入的紧武,幫助文檔上說,- (id)prepareWithInvocationTarget:(id)target方法執(zhí)行時(shí)會(huì)調(diào)用- (void)forwardInvocation:(NSInvocation *)anInvocation敏储。這就說明NSUndoManager重載了該方法阻星。我們知道,當(dāng)方法找不到函數(shù)體時(shí)在crash前會(huì)走轉(zhuǎn)發(fā)流程虹曙,轉(zhuǎn)發(fā)時(shí)在調(diào)用- (void)forwardInvocation:(NSInvocation *)anInvocation前會(huì)調(diào)用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector方法迫横,如果在我在測試的類中實(shí)現(xiàn)該方法,是能夠被調(diào)用的酝碳。假如我注冊一個(gè)變量a,并且對他注冊一個(gè)撤消操作矾踱,當(dāng)a值改變時(shí),我是可以進(jìn)行撤消 的疏哗,當(dāng)撤消后通過redo可以重做呛讲。接下來貼出幾行簡單的代碼:

registerUndoWithTarget:
prepareWithInvocationTarget:

? 另外我們還可以為NSUndoManager添加一個(gè)通知中心,來監(jiān)聽其狀態(tài)的變化返奉,需要注意的是在何時(shí)的地方移除監(jiān)聽贝搁。

NSNotificationCenter

總結(jié):理解英文文檔有點(diǎn)費(fèi)勁,如果有理解錯(cuò)誤的地方敬請批評(píng)芽偏、指出雷逆,demo功能過于簡單(也是為了更好的理解),我會(huì)持續(xù)更新污尉,共同學(xué)習(xí)進(jìn)步.demo地址:https://github.com/luguoliang/Model.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膀哲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子被碗,更是在濱河造成了極大的恐慌某宪,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锐朴,死亡現(xiàn)場離奇詭異兴喂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門衣迷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畏鼓,“玉大人,你說我怎么就攤上這事蘑险〉沃祝” “怎么了岳悟?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵佃迄,是天一觀的道長。 經(jīng)常有香客問我贵少,道長呵俏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任滔灶,我火速辦了婚禮普碎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘录平。我一直安慰自己麻车,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布斗这。 她就那樣靜靜地躺著动猬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪表箭。 梳的紋絲不亂的頭發(fā)上赁咙,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音免钻,去河邊找鬼彼水。 笑死,一個(gè)胖子當(dāng)著我的面吹牛极舔,可吹牛的內(nèi)容都是我干的凤覆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拆魏,長吁一口氣:“原來是場噩夢啊……” “哼盯桦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起稽揭,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤俺附,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后溪掀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體事镣,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了璃哟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氛琢。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖随闪,靈堂內(nèi)的尸體忽然破棺而出阳似,到底是詐尸還是另有隱情,我是刑警寧澤铐伴,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布撮奏,位于F島的核電站,受9級(jí)特大地震影響当宴,放射性物質(zhì)發(fā)生泄漏畜吊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一户矢、第九天 我趴在偏房一處隱蔽的房頂上張望玲献。 院中可真熱鬧,春花似錦梯浪、人聲如沸捌年。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽礼预。三九已至,卻和暖如春抹锄,著一層夾襖步出監(jiān)牢的瞬間逆瑞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國打工伙单, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留获高,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓吻育,卻偏偏與公主長得像念秧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子布疼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容