欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

IOS觀察者設(shè)計模式

 更新時間:2015年12月09日 14:28:00   投稿:mrr  
什么是觀察者模式 什么是觀察者模式?你曾經(jīng)訂閱過報紙嗎?在訂閱報紙的時候,你不用去任何地方,只需要將你的個人地址信息以及訂閱信息告訴出版社,出版社就知道如何將相關(guān)報紙傳遞,本文給大家介紹ios觀察者模式,感興趣的朋友一起看看吧

什么是觀察者模式?我們先打個比方,這就像你訂報紙。比如你想知道美國最近放生了些新聞,你可能會訂閱一份美國周刊,然后一旦美國有了新的故事,美國周刊就發(fā)一刊,并郵寄給你,當(dāng)你收到這份報刊,然后你就能夠了解美國最新的動態(tài)。其實這就是觀察者模式,A對B的變化感興趣,就注冊為B的觀察者,當(dāng)B發(fā)生變化時通知A,告知B發(fā)生了變化。這是一種非常典型的觀察者的用法,我把這種使用方法叫做經(jīng)典觀察者模式。當(dāng)然與之相對的還有另外一種觀察者模式——廣義觀察者模式。

從經(jīng)典的角度看,觀察者模式是一種通知變化的模式,一般認為只在對象發(fā)生變化感興趣的場合有用。主題對象知道有觀察者存在,設(shè)置會維護觀察者的一個隊列;而從廣義的角度看,觀察者模式是中傳遞變化數(shù)據(jù)的模式,需要查看對象屬性時就會使用的一種模式,主題對象不知道觀察者的存在,更像是圍觀者。需要知道主題對象的狀態(tài),所以即使在主題對象沒有發(fā)生改變的時候,觀察者也可能會去訪問主題對象。換句話說廣義觀察者模式,是在不同的對象之間傳遞數(shù)據(jù)的一種模式。

觀察者模式應(yīng)當(dāng)是在面向?qū)ο缶幊讨斜淮笠?guī)模使用的設(shè)計模式之一。從方法論的角度出發(fā),傳統(tǒng)的認知論認為,世界是由對象組成的,我們通過不停的觀察和了解就能夠了解對象的本質(zhì)。整個人類的認知模型就是建立在“觀察”這種行為之上的。我們通過不停與世界中的其他對象交互,并觀察之來了解這個世界。同樣,在程序的世界中,我們構(gòu)建的每一個實例,也是通過不不停的與其他對象交互(查看其他對象的狀態(tài),或者改變其他對象的狀態(tài)),并通過觀察其他實例的變化并作出響應(yīng),以來完成功能。這也就是,為什么會把觀察模式單獨提出來,做一個專門的剖析的原因——在我看來他是很多其他設(shè)計模式的基礎(chǔ)模式,并且是編程中極其重要的一種設(shè)計模式。

經(jīng)典觀察者模式

經(jīng)典觀察者模式被認為是對象的行為模式,又叫發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。經(jīng)典觀察者模式定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象。這個主題對象在狀態(tài)上發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己或者做出相應(yīng)的一些動作。在文章一開始舉的例子就是典型觀察者模式的應(yīng)用。

而在IOS開發(fā)中我們可能會接觸到的經(jīng)典觀察者模式的實現(xiàn)方式,有這么幾種:NSNotificationCenter、KVO、Delegate等

感知通知方式

在經(jīng)典觀察者模式中,因為觀察者感知到主題對象變化方式的不同,又分為推模型和拉模型兩種方式。

推模型

主題對象向觀察者推送主題的詳細信息,不管觀察者是否需要,推送的信息通常是主題對象的全部或者部分數(shù)據(jù)。推模型實現(xiàn)了觀察者和主題對象的解耦,兩者之間沒有過度的依賴關(guān)系。但是推模型每次都會以廣播的方式,向所有觀察者發(fā)送通知。所有觀察者被動的接受通知。當(dāng)通知的內(nèi)容過多時,多個觀察者同時接收,可能會對網(wǎng)絡(luò)、內(nèi)存(有些時候還會涉及IO)有較大影響。

在IOS中典型的推模型實現(xiàn)方式為NSNotificationCenter和KVO。

NSNotificationCenter

NSnotificationCenter是一種典型的有調(diào)度中心的觀察者模式實現(xiàn)方式。以NSNotificationCenter為中心,觀察者往Center中注冊對某個主題對象的變化感興趣,主題對象通過NSNotificationCenter進行變化廣播。這種模型就是文章開始發(fā)布訂閱報紙在OC中的一種類似實現(xiàn)。所有的觀察和監(jiān)聽行為都向同一個中心注冊,所有對象的變化也都通過同一個中心向外廣播。

SNotificationCenter就像一個樞紐一樣,處在整個觀察者模式的核心位置,調(diào)度著消息在觀察者和監(jiān)聽者之間傳遞。

一次完整的觀察過程如上圖所示。整個過程中,關(guān)鍵的類有這么幾個(介紹順序按照完成順序):

觀察者Observer,一般繼承自NSObject,通過NSNotificationCenter的addObserver:selector:name:object接口來注冊對某一類型通知感興趣.在注冊時候一定要注意,NSNotificationCenter不會對觀察者進行引用計數(shù)+1的操作,我們在程序中釋放觀察者的時候,一定要去報從center中將其注銷了。

- (void) handleMessage:(NSNotification*)nc{
//解析消息內(nèi)容
NSDictionary* userInfo = [nc userInfo];
}
- (void) commonInit
{
//注冊觀察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMessage:) name:kDZTestNotificatonMessage object:nil];
}

通知中心NSNotificationCenter,通知的樞紐。
主題對象,被觀察的對象,通過postNotificationName:object:userInfo:發(fā)送某一類型通知,廣播改變。

- (void) postMessage
{
[[NSNotificationCenter defaultCenter] postNotificationName:kDZTestNotificatonMessage object:Nil userInfo:@{}];
}

通知對象NSNotification,當(dāng)有通知來的時候,Center會調(diào)用觀察者注冊的接口來廣播通知,同時傳遞存儲著更改內(nèi)容的NSNotification對象。

apple版實現(xiàn)的NotificationCenter讓我用起來不太爽的幾個小問題

在使用NSNotificationCenter的時候,從編程的角度來講我們往往不止是希望能夠做到功能實現(xiàn),還能希望編碼效率和整個工程的可維護性良好。而Apple提供的以NSNotificationCenter為中心的觀察者模式實現(xiàn),在可維護性和效率上存在以下缺點:

每個注冊的地方需要同時注冊一個函數(shù),這將會帶來大量的編碼工作。仔細分析能夠發(fā)現(xiàn),其實我們每個觀察者每次注冊的函數(shù)幾乎都是雷同的。這就是種變相的CtrlCV,是典型的丑陋和難維護的代碼。
每個觀察者的回調(diào)函數(shù),都需要對主題對象發(fā)送來的消息進行解包的操作。從UserInfo中通過KeyValue的方式,將消息解析出來,而后進行操作。試想一下,工程中有100個地方,同時對前面中在響應(yīng)變化的函數(shù)中進行了解包的操作。而后期需求變化需要多傳一個內(nèi)容的時候,將會是一場維護上的災(zāi)難。

當(dāng)大規(guī)模使用觀察者模式的時候,我們往往在dealloc處加上一句:

[[NSNotificationCenter defaultCenter] removeObserver:self]

而在實際使用過程中,會發(fā)現(xiàn)該函數(shù)的性能是比較低下的。在整個啟動過程中,進行了10000次RemoveObserver操作,

@implementation DZMessage
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
....
for (int i = ; i < ; i++) {
DZMessage* message = [DZMessage new];
}

通過下圖可以看出這一過程消耗了23.4%的CPU,說明這一函數(shù)的效率還是很低的。

這還是只有一種消息類型的存在下有這樣的結(jié)果,如果整個NotificationCenter中混雜著多種消息類型,那么恐怕對于性能來說將會是災(zāi)難性的。

for (int i = 0 ; i < 10000; i++) {
DZMessage* message = [DZMessage new];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle) name:[@(i) stringValue] object:nil];
}

增加了多種消息類型之后,RemoveObserver占用了啟動過程中63.9%的CPU消耗。

而由于Apple沒有提供Center的源碼,所以修改這個Center幾乎不可能了。

改進版的有中心觀察者模式(DZNotificationCenter)

GitHub地址 在設(shè)計的時候考慮到以上用起來不爽的地方,進行了優(yōu)化:

將解包到執(zhí)行函數(shù)的操作進行了封裝,只需要提供某消息類型的解包block和消息類型對應(yīng)的protocol,當(dāng)有消息到達的時候,消息中心會進行統(tǒng)一解包,并直接調(diào)用觀察者相應(yīng)的函數(shù)。
對觀察者的維護機制進行優(yōu)化(還未做完),提升查找和刪除觀察者的效率。
DZNotificationCenter的用法和NSNotificationCenter在注冊和注銷觀察者的地方是一樣的,不一樣的地方在于,你在使用的時候需要提供解析消息的block。你可以通過兩種方式來提供。

直接注冊的方式

[DZDefaultNotificationCenter addDecodeNotificationBlock:^SEL(NSDictionary *userInfo, NSMutableArray *__autoreleasing *params) {
NSString* key = userInfo[@"key"];
if (params != NULL) {
*params = [NSMutableArray new];
}
[*params addObject:key];
return @selector(handleTestMessageWithKey:);
} forMessage:kDZMessageTest];

實現(xiàn)DZNotificationInitDelegaete協(xié)議,當(dāng)整個工程中大規(guī)模使用觀察者的時候,建議使用該方式。這樣有利于統(tǒng)一管理所有的解析方式。

- (DZDecodeNotificationBlock) decodeNotification:(NSString *)message forCenter:(DZNotificationCenter *)center
{
if (message == kDZMessageTest) {
return ^(NSDictionary* userInfo, NSMutableArray* __autoreleasing* params){
NSString* key = userInfo[@"key"];
if (params != NULL) {
*params = [NSMutableArray new];
}
[*params addObject:key];
return @selector(handlePortMessage:);
};
}
return nil;
}

在使用的過程中為了,能夠保證在觀察者處能夠回調(diào)相同的函數(shù),可以實現(xiàn)針對某一消息類型的protocol

@protocol DZTestMessageInterface <NSObject>
- (void) handleTestMessageWithKey:(NSString*)key;
@end

這樣就能夠保證,在使用觀察者的地方不用反復(fù)的拼函數(shù)名和解析消息內(nèi)容了。

@interface DZViewController () <DZTestMessageInterface>
@end
@implementation DZViewController
....
- (void) handleTestMessageWithKey:(NSString *)key
{
self.showLabel.text = [NSString stringWithFormat:@"get message with %@", key];
}
....

KVO

KVO的全稱是Key-Value Observer,即鍵值觀察。是一種沒有中心樞紐的觀察者模式的實現(xiàn)方式。一個主題對象管理所有依賴于它的觀察者對象,并且在自身狀態(tài)發(fā)生改變的時候主動通知觀察者對象。 讓我們先看一個完整的示例:

static NSString* const kKVOPathKey = @"key";
@implementation DZKVOTest
- (void) setMessage:(DZMessage *)message
{
if (message != _message) {
if (_message) {
[_message removeObserver:self forKeyPath:kKVOPathKey];
}
if (message) {
[message addObserver:self forKeyPath:kKVOPathKey options:NSKeyValueObservingOptionNew context:Nil];
}
_message = message;
}
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqual:kKVOPathKey] && object == _message) {
NSLog(@"get %@",change);
}
}
- (void) postMessage
{
_message.key = @"asdfasd";
}
@end

完成一次完整的改變通知過程,經(jīng)過以下幾次過程:

注冊觀察者[message addObserver:self forKeyPath:kKVOPathKey options:NSKeyValueObservingOptionNew context:Nil];
更改主題對象屬性的值,即觸發(fā)發(fā)送更改的通知 _message.key = @"asdfasd";
在制定的回調(diào)函數(shù)中,處理收到的更改通知

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqual:kKVOPathKey] && object == _message) {
NSLog(@"get %@",change);
}
}

注銷觀察者 [_message removeObserver:self forKeyPath:kKVOPathKey];

KVO實現(xiàn)原理

一般情況下對于使用Property的屬性,objc會為其自動添加鍵值觀察功能,你只需要寫一句@property (noatomic, assign) float age 就能夠獲得age的鍵值觀察功能。而為了更深入的探討一下,KVO的實現(xiàn)原理我們先手動實現(xiàn)一下KVO:

@implementation DZKVOManual
- (void) setAge:(int)age
{
[self willChangeValueForKey:kKVOPathAge];
if (age !=_age) {
_age = age;
}
[self didChangeValueForKey:kKVOPathAge];
}
//經(jīng)驗證 會先去調(diào)用automaticallyNotifiesObserversForKey:當(dāng)該函數(shù)沒有時才會調(diào)用automaticallyNotifiesObserversOfAge。這個函數(shù)應(yīng)該是編譯器,自動增加的一個函數(shù),使用xcode能夠自動提示出來。的確很強大。
//+(BOOL) automaticallyNotifiesObserversOfAge
//{
// return NO;
//}
+ (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key
{
if (key ==kKVOPathAge) {
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}
@end

首先,需要手動實現(xiàn)屬性的 setter 方法,并在設(shè)置操作的前后分別調(diào)用 willChangeValueForKey: 和 didChangeValueForKey方法,這兩個方法用于通知系統(tǒng)該 key 的屬性值即將和已經(jīng)變更了;

其次,要實現(xiàn)類方法 automaticallyNotifiesObserversForKey,并在其中設(shè)置對該 key 不自動發(fā)送通知(返回 NO 即可)。這里要注意,對其它非手動實現(xiàn)的 key,要轉(zhuǎn)交給 super 來處理。

在這里的手動實現(xiàn),主要是手動實現(xiàn)了主題對象變更向外廣播的過程。后續(xù)如何廣播到觀察者和觀察者如何響應(yīng)我們沒有實現(xiàn),其實這兩個過程apple已經(jīng)封裝的很好了,猜測一下的話,應(yīng)該是主題對象會維護一個觀察者的隊列,當(dāng)本身屬性發(fā)生變動,接受到通知的時候,找到相關(guān)屬性的觀察者隊列,依次調(diào)用observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context來廣播更改。 還有一個疑問,就是在自動實現(xiàn)KVO的時候,系統(tǒng)是否和我們手動實現(xiàn)做了同樣的事情呢?

自動實現(xiàn)KVO及其原理

我們仔細來觀察一下在使用KVO的過程中類DZMessage的一個實例發(fā)生了什么變化: 在使用KVO之前:

當(dāng)調(diào)用Setter方法,并打了斷點的時候:

神奇的發(fā)現(xiàn)類的isa指針發(fā)生了變化,我們原本的類叫做DZMessage,而使用KVO后類名變成了NSKVONotifying_DZMessage。這說明objc在運行時對我們的類做了些什么。

我們從Apple的文檔Key-Value Observing Implementation Details找到了一些線索。

Automatic key-value observing is implemented using a technique called isa-swizzling. The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table.This dispatch table essentially contains pointers to the methods the class implements, among other data. When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class. As a result the value of the isa pointer does not necessarily reflect the actual class of the instance. You should never rely on the isa pointer to determine class membership. Instead, you should use the class method to determine the class of an object instance.

當(dāng)某一個類的實例第一次使用KVO的時候,系統(tǒng)就會在運行期間動態(tài)的創(chuàng)建該類的一個派生類,該類的命名規(guī)則一般是以NSKVONotifying為前綴,以原本的類名為后綴。并且將原型的對象的isa指針指向該派生類。同時在派生類中重載了使用KVO的屬性的setter方法,在重載的setter方法中實現(xiàn)真正的通知機制,正如前面我們手動實現(xiàn)KVO一樣。這么做是基于設(shè)置屬性會調(diào)用 setter 方法,而通過重寫就獲得了 KVO 需要的通知機制。當(dāng)然前提是要通過遵循 KVO 的屬性設(shè)置方式來變更屬性值,如果僅是直接修改屬性對應(yīng)的成員變量,是無法實現(xiàn) KVO 的。

同時派生類還重寫了 class 方法以“欺騙”外部調(diào)用者它就是起初的那個類。因此這個對象就成為該派生類的對象了,因而在該對象上對 setter 的調(diào)用就會調(diào)用重寫的 setter,從而激活鍵值通知機制。此外,派生類還重寫了 dealloc 方法來釋放資源。

拉模型

拉模型是指主題對象在通知觀察者的時候,只傳遞少量信息或者只是通知變化。如果觀察者需求要更具體的信息,由觀察者主動從主題對象中拉取數(shù)據(jù)。相比推模型來說,拉模型更加自由,觀察者只要知道有情況發(fā)生就好了,至于什么時候獲取、獲取那些內(nèi)容、甚至是否獲取都可以自主決定。但是,卻存在兩個問題:

如果某個觀察者響應(yīng)過慢,可能會漏掉之前通知的內(nèi)容
觀察者必須保存一個對目標對象的引用,而且還需要了解主題對象的結(jié)構(gòu),這就使觀察者產(chǎn)生了對主題對象的依賴。
可能每種設(shè)計模式都會存在或多或少的一些弊端,但是他們的確能夠解決問題,也有更多有用的地方。在使用的時候,就需要我們權(quán)衡利弊,做出一個合適的選擇。而工程師的價值就體現(xiàn)在,能夠在紛繁復(fù)雜的工具世界中找到最有效的那個。而如果核桃沒被砸開,不是你手力氣不大的問題,而是你選錯了工具,誰讓你非得用門縫夾,不用錘子呢!

當(dāng)然,上面那段屬于題外話。言歸正傳,在OBJC編程中,典型的一種拉模型的實現(xiàn)是delegate??赡芎芏嗳藭煌馕业挠^點,說delegate應(yīng)當(dāng)是委托模式。好吧,我不否認,delegate的確是委托模式的一種極度典型的實現(xiàn)方式。但是這并不妨礙,他也是一種觀察者模式。其實本來各種設(shè)計模式之間就不是涇渭分明的。在使用和解釋的時候,只要你能夠說得通,而且能夠解決問題就好了,沒必要糾纏他們的名字。而在通知變化這個事情上delegate的確是能夠解決問題的。

我們來看一個使用delegate實現(xiàn)拉模型的觀察者的例子:

先實現(xiàn)一個delegate方便注冊觀察者,和回調(diào)函數(shù)

@class DZClient;
@protocol DZClientChangedDelegate <NSObject>
- (void) client:(DZClient*)client didChangedContent:(NSString*)key;
@end
@interface DZClient : NSObject
@property (nonatomic, weak) id<DZClientChangedDelegate> delegate;
@property (nonatomic, strong) NSString* key;
@end

注冊觀察者

//DZAppDelegate
DZClient* client = [DZClient new];
client.delegate = self;
client.key = @"aa";

當(dāng)主題對象的屬性發(fā)生改變的時候,發(fā)送內(nèi)容有變化的通知

@implementation DZClient
- (void) setKey:(NSString *)key
{
if (_key != key) {
_key = key;
if ([_delegate respondsToSelector:@selector(client:didChangedContent:)]) {
[_delegate client:self didChangedContent:@"key"];
}
}
}

觀察者收到主題對象有變化的通知后,主動去拉取變化的內(nèi)容。

//DZAppDelegate
- (void) client:(DZClient *)client didChangedContent:(NSString *)key
{
if ([key isEqual: @"key"]) {
NSLog(@"get changed key %@",client.key);
}
}

廣義觀察者模式

在上面介紹了,觀察者被動的接受主題改變的經(jīng)典意義上的觀察者模式之后,我們再來看一下廣義觀察者模式。當(dāng)然上面所講的經(jīng)典觀察者模式,也是一種一種傳遞數(shù)據(jù)的方式。廣義觀察者涵蓋了經(jīng)典觀察者模式。

往往我們會有需要在“觀察者”和“主題對象”之間傳遞變化的數(shù)據(jù)。而這種情況下,主題對象可能不會像經(jīng)典觀察者模式中的主題對象那樣勤勞,在發(fā)生改變的時候不停的廣播。在廣義觀察者模式中,主題對象可能是懶惰的,而是由觀察者通過不停的查詢主題對象的狀態(tài),來獲知改變的內(nèi)容。

我們熟悉的服務(wù)器CS架構(gòu),始終比較典型的冠以觀察者模式,服務(wù)器是伺服的,等待著客戶端的訪問,客戶端通過訪問服務(wù)器來獲取最新的內(nèi)容,而不是服務(wù)器主動的推送。

之所以,要提出廣義觀察者模式這樣一個概念。是為了探討一下觀察者模式的本質(zhì)。方便我們能夠更深刻的理解觀察者模式,并且合理的使用它。而且我們平時更多的將注意力放在了通知變化上面,而觀察者根本的目的是在于,在觀察者和主題對象之間,傳遞變化的數(shù)據(jù)。這些數(shù)據(jù)可能是變化這個事件本身,也可能是變化的內(nèi)容,甚至可能是一些其他的內(nèi)容。

從變化數(shù)據(jù)傳遞的角度來思考的話,能夠?qū)崿F(xiàn)這個的模式和策略實在是數(shù)不勝數(shù),比如傳統(tǒng)的網(wǎng)絡(luò)CS模型,比如KVC等等。在這里就先不詳細展開討論了。

以上所述是本文給大家介紹的ios觀察者設(shè)計模式,希望大家喜歡。

相關(guān)文章

  • ios學(xué)習(xí)筆記之基礎(chǔ)數(shù)據(jù)類型的轉(zhuǎn)換

    ios學(xué)習(xí)筆記之基礎(chǔ)數(shù)據(jù)類型的轉(zhuǎn)換

    在編碼過程中,數(shù)據(jù)的處理是必要的。眾多數(shù)據(jù)中,NSString、NSData、NSArray、 NSDictionary等數(shù)據(jù)類型是常用的,對付它們?nèi)菀祝窃诙鄠€數(shù)據(jù)類型之間轉(zhuǎn)換就需要技巧了。本文主要給大家介紹ios中基礎(chǔ)數(shù)據(jù)類型的轉(zhuǎn)換,有需要的下面來一起看看吧。
    2016-11-11
  • iOS移動端(H5)alert/confirm提示信息去除網(wǎng)址(URL)

    iOS移動端(H5)alert/confirm提示信息去除網(wǎng)址(URL)

    這篇文章主要介紹了iOS移動端(H5)alert/confirm提示信息去除網(wǎng)址URL,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • IOS應(yīng)用程序多語言本地化的兩種解決方案

    IOS應(yīng)用程序多語言本地化的兩種解決方案

    本篇文章介紹了IOS應(yīng)用程序多語言本地化解決方案,這里整理了詳細的解決辦法,有需要的小伙伴可以參考下。
    2016-11-11
  • iOS組件化開發(fā)實戰(zhàn)記錄

    iOS組件化開發(fā)實戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于iOS組件化開發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • iOS開發(fā)中的ViewController轉(zhuǎn)場切換效果實現(xiàn)簡介

    iOS開發(fā)中的ViewController轉(zhuǎn)場切換效果實現(xiàn)簡介

    這篇文章主要介紹了iOS開發(fā)中的ViewController轉(zhuǎn)場切換效果實,主要針對iOS7以后新加入的API進行講解,需要的朋友可以參考下
    2015-09-09
  • iOS中的導(dǎo)航欄UINavigationBar與工具欄UIToolBar要點解析

    iOS中的導(dǎo)航欄UINavigationBar與工具欄UIToolBar要點解析

    UINavigation可以附著于導(dǎo)航控制器之中使用,也可以在controller中單獨使用,這里我們將來看iOS中的導(dǎo)航欄UINavigationBar與工具欄UIToolBar要點解析.
    2016-06-06
  • IOS 開發(fā)之對象為空的判斷(nil、null)詳解

    IOS 開發(fā)之對象為空的判斷(nil、null)詳解

    這篇文章主要介紹了IOS 開發(fā)之對象為空的判斷(nil、null)詳解的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 總結(jié)iOS實現(xiàn)漸變顏色的三種方法

    總結(jié)iOS實現(xiàn)漸變顏色的三種方法

    這篇文章主要給大家總結(jié)了iOS實現(xiàn)漸變顏色的三種方法,分別是利用CAGradientLayer實現(xiàn)漸變、Core Graphics相關(guān)方法實現(xiàn)漸變以及用CAShapeLayer作為layer的mask屬性實現(xiàn),大家可以根據(jù)自己的需要選擇使用,下面來一起看看吧。
    2016-10-10
  • iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用

    iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用

    這篇文章主要介紹了iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用的方法,實例代碼為傳統(tǒng)的Objective-C語言,需要的朋友可以參考下
    2016-03-03
  • iOS自動移除KVO觀察者的實現(xiàn)方法

    iOS自動移除KVO觀察者的實現(xiàn)方法

    在 Apple 的應(yīng)用開發(fā)里 KVO 提供了一個途徑,使對象(觀察者)能夠觀察其他對象(被觀察者)的屬性,當(dāng)被觀察者的屬性發(fā)生變化時,觀察者就會被告知該變化。下面這篇文章主要給大家介紹了關(guān)于iOS如何自動移除KVO觀察者的實現(xiàn)方法,需要的朋友可以參考下。
    2017-12-12

最新評論