【學習iOS高質量開發】——協議與分類

文章目錄

  • 一、通過委托與數據源協議進行對象間通信
    • 1.委托模式
    • 2.要點
  • 二、將類的實現代碼分散到便于管理的數個分類之中
    • 1.如何實現
    • 2.要點
  • 三、總是為第三方類的分類名稱加前綴
    • 1.為什么總是為第三方類的分類名稱加前綴
    • 2.要點
  • 三、勿在分類中聲明屬性
    • 1.勿在分類中聲明屬性的原因
    • 2.要點
  • 四、使用“class-continuation分類”隱藏實現細節
    • 1.什么是class-continuation分類
    • 2.“class-continuation分類”的合理用法
    • 3.要點
    • 五、通過協議提供匿名對象
    • 1.什么是匿名對象
    • 2.如何使用
    • 3.要點


一、通過委托與數據源協議進行對象間通信

1.委托模式

對象之間經常需要相互 通信,而通信方式有很多種。OC開發者廣泛使用一種“委托模式”的編程設計模式來實現對象間的通信,該模式的主旨是:定義一套接口,某對象若想接收另一個對象的委托,則需遵從此接口,以便于成為其“委托對象”,而這“另一個對象”則可以給委托對象回傳一些信息,也可以在發生相關事件時通知委托對象。
此模式可將數據與業務邏輯解藕。比如說,用戶界面里有個現實一系列數據所用的視圖,那么,此視圖只應包含顯示數據所需的邏輯代碼,而不應決定要顯示和中數據以及數據之間如何交互等問題。視圖對象的屬性中,可以包含負責數據與事件處理的對象。這兩種對象分別稱為:“數據源”與“委托”。

@protocol EOCNetworkFetcherDelegate 
- (void) networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
- (void) networkFetcher:(EOCNetworkFetcher *)fetcher didFailWithError:(NSError *)error;
@end

有了這個協議之后,類就可以用一個屬性來存放其委托對象了。在本例總,這個類就是EOCNetworkFetcher類。此類的接口可以寫成這樣:

@interface EOCNetworkFetcher : NSObject
@property (nonatomic, weak) id <EOCNetworkFetcherDelegate> delegate;
@end

這個id類型的協議屬性一定要定義成weak,而非strong,因為兩者之間必須為“非擁有關系”。一般情況下,扮演delegate的那個對象也要持有本對象,直到用完本對象之后,才會釋放。
假如聲明屬性的時候用strong將本對象與委托對象之間定為“擁有關系”,那么就會引入“保留環”。因此, 本類中存放委托對象的這個屬性要么定義為weak,要么定義為unsafe_unretained。如果需要在相關對象銷毀時自動清空,則定義為前者,若不需要自動清空,則定義為后者。
在這里插入圖片描述
某類若要遵從委托協議,可以在其接口中聲明,也可以在“分類”中聲明。如果要象外界公布此類實現了某協議,那么就在接口中聲明,而如果這個協議是個委托協議的話,那么通常只會在類的內部使用。所以說,這種情況一般都是在“分類”里聲明的:

@implementation EOCDataModel () <EOCNetworkFetcherDelegate>
@end
@implementation EOCDataModel 
- (void) networkFetcher: (EOCNetworkFetcher *)fetcher didReceiveData: (NSData *) data {/* Handle data */
}
- (void) networkFetcher: (EOCNetworkFetcher *)fetcehr didFailWithError: (NSError *)error {/* Handle error */;
}
@end

委托協議中的方法一般都是“可選的”,因為扮演“受委托者”角色的這個對象未必關心其中的所有方法。這時我們就可以使用@optional關鍵字來標注其大部分或全部的方法:

@protocol EOCNetworkFetcherDelegate
@optional
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didReceiveData:(NSData *)data;
- (void)networkFetcher:(EOCNetworkFetcher *)fetcher didFailWithError: (NSError *)error;
@end

然而在委托對象上調用可選方法時,就必須提前使用類型信息查詢方法,來判斷這個委托對象能否響應相關選擇子。以EOCNetworkFetcher為例,應該這樣寫:

NSData *data = /* data obtained from network */;
if ([_delegate respondsToSelector: @selector(networkFetcher:didReceiveData:)]) {[_delegate networkFetcher:self didReceiveData:data];
}

判斷委托對象是否實現了相關方法,如果實現了就調用,如果沒有實現就不執行任何操作(因為給nil發送消息將使if語句的值成為false)。
也可以像下方,傳入發起委托的實例,然后在delegete對象在實現相關方法時,根據傳入的實例分別執行不同的代碼子:

- (void)networkFetcher: (EOCNetworkFetcher *)fetcher didReceiveData: (NSData *)data {if (fetcher == _myFetcherA) {/* Handle data */} else if (fetcher == _myFetcherB) {/* Handle data */}
}

上面這段代碼表明,委托對象有兩個不同的“網絡數據獲取器”,所以他們必須根據所傳的參數判斷到底是哪個EOCNetworkFetcher獲取到了數據。若沒有此信息,則委托對像在同一時間只能使用一個網絡請求獲取器,這么做不太好。
delegate里的方法也可以用于從獲取委托對象中獲取信息。比方說,EOCNetworkFetcher類也許想提供一種機制:在獲取數據的時候如果遇到了“重定向”,那么將詢問其委托對象是否應該發生重定向。delegate對象中的相關方法也可以寫成這樣:

- (BOOL)networkFetcher: (EOCNetworkFetcher *)fetcher shouldFollowRedirectToURL: (NSURL *) url;

用結構體緩存委托對象是否能響應特定的選擇子。實現緩存功能所用的代碼可以寫在delegate屬性所對應的設置方法里:

- (void) setDelegate:(id<EOCNetworkFetcher>) delegate {_delegate = delegate;_delegateFlags.didReceiveData = [delegate respondsToSelector: @selector(networkFetcher:didReceiveData:)];_delegateFlags.didFailWithError = [delegate respondsToSelector: @selector(networkFetcher:didFailWithError:)];_delegateFlags.didUpdateProgressTo = [delegate respondsToSelector:@selector(networkFetcher:didUpdateProgressTo:)];
}

2.要點

  • 委托模式為對象提供了一套接口,使其可由此將相關事件告知其他對象。
  • 將委托對象應該支持的接口定義成協議,在協議中把可能需要處理的事件定義成方法。
  • 當某對象需要從另外一個對象中獲取數據時,可以使用委托模式。這種情況下,該模式亦稱“數據源協議”
  • 若有必要,可實現含有位段的結構體,將委托對象是否能響應相關協議方法這一信息緩存至其中。

二、將類的實現代碼分散到便于管理的數個分類之中

1.如何實現

OC中有一個分類機制,但是通常是使用它來補充一個需要的類,但其實還有更好的用途,那就是用來規劃我們的代碼,我們可以通過OC的“分類”機制,把類代碼按邏輯劃入幾個分區中。就像這樣:

#import <Foundation/Foundation.h>@interface EOCPerson : NSObject
@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;
@property (nonatomic, strong, readonly) NSArray *friends;- (id)initWithFirstName: (NSString *)firstName andLastName:(NSString *)lastName;/ * Friendship methods * /
- (void) addFriend:(EOCPerson *)person;
- (void) removeFriend:(EOCPerson *)person;
- (BOOL) isFriendsWith:(EOCPerson *)person;/ * Work methods * /
- (void) performDaysWork;
- (void) takeVacationFromWork;/ * Play methods * /
- (void) goToTheCinema;
- (void) goToSportsGame;@end

現在,類的實現代碼按照方法分成了好幾個部分。所以說,這項語言特性就叫做“分類”。本例中,類的基本要素(諸如屬性與初始化方法等)都聲明在“主實現”里。可是,隨著分類數量增加,當前這份實現文件很快就膨脹得無法管理了,此時就可以把每個分類提取到各自的文件中去,以EOCPerson為例,可以按照其分類拆分成下列幾個文件:

EOCPerson + Friendship(.h/.m)
EOCPerson + Work(.h/.m)
EOCPerson + Play(.h/.m)
//EOCPerson + Friendship.h
#import "EOCPerson.h"@interface EOCPerson (Friendship)
- (void) addFriend:(EOCPerson *)person;
- (void) removeFriend:(EOCPerson *)person;
- (void) isFriendsWith:(EOCPerson *)person;
@end//EOCPerson + Friendship.m
#import "EOCPerson + Friendship.h"@implementation EOCPerson (Friendship)
- (void) addFriend: (EOCPerson *)person {/* ... */
}
- (void) removeFriend:(EOCPerson *)person {/* ... */
}
- (BOOL) isFriendsWith:(EOCPerson *)person {/* ... */
}@end

并且我們之前有說過私有方法的命名,通過特殊的前綴將私有方法指示出來,那么我們學了分類規劃之后,我們還可以通過創建一個分類,這個分類其中全是私有方法,通過這種方法將這些私有方法都規劃到一個類中,當然其還是的遵循之前的命名規則。

2.要點

  • 使用分類機制把類的實現代碼劃分成易于管理的小塊。
  • 將應該視為“私有”的方法歸入名叫Private的分類中,以隱藏實現細節。

三、總是為第三方類的分類名稱加前綴

1.為什么總是為第三方類的分類名稱加前綴

分類機制通常用 于向無源碼的既有類中新增功能。這個特性極為強大,但在使用時也很 容易忽視其中可能產生的問題。這個問題在于:分類中的方法是直接添加在類里面的,它們 就好比這個類中的固有方法。將分類方法加人類中這一操作是在運行期系統加載分類時完成 的。運行期系統會把分類中所實現的每個方法都加人類的方法列表中。如果類中本來就有此 方法,而分類又實現了一次,那么分類中的方法會覆蓋原來那一份實現代碼。實際上可能會 發生很多次覆蓋,比如某個分類中的方法覆蓋了“ 主實現” 中的相關方法,而另外一個分類 中的方法又覆蓋了這個分類中的方法。多次覆蓋的結果以最后 一個分類為準。
比方說,要給NSString 添加分類,并在其中提供一些輔助方法,用于處理與HTTP URL 有關的字符串。你可能會把分類寫成這樣:

@interface NSString (HTTP)//Encode a string with URL encoding
- (NSString *)urlEncodeString;//Decode a URL encoded string
- (NSString *)urlDecodedString;@end 

現在看起來沒什么問題,可是,如果還有 一個分類也往NSString里添加方法,那會如何呢?那個分類里可能也有個名叫urIEncodedstring的方法,其代碼與你所添加的大同小 異,但卻不能正確實現你所需的功能。那個分類的加載時機如果晚于你所寫的這個分類,那 么其代碼就會把你的那 一份覆蓋掉,這樣的話,你在代碼中調用urlEncodedstring 方法時,實際執行的是那個分類里的實現代碼。由于其執行結果和你預期的值不同所以自己所寫 的那些代碼也許就無法正常運行了。這種bug很難追查因為你可能意識不到實際執行的 urlEncodedString代碼并不是自己實現的那一份。
要解決此問題,**一般的做法是:以命名空間來區別各個分類的名稱與其中所定義的方法。 想在Objective-C中實現命名空問功能,只有 一個辦法,就是給相關名稱都加上某個共用的 前綴。與給類名加前級時所應考慮的因素相似,給分類所加的前綴也要選 得怡當才行。**一般來說,這個前級應該與應用程序或程序庫中其他地方所用的前綴相同。 于 是,我們可以給剛才那個NSString分類加上ABC前綴:

@interface NSString (ABC_HTTP)//Encode a string with URL encoding
- (NSString *)abc_urlEncodedString;//Decode a URL encoded string
- (NSString *)abc_urlDecodedString;@end

2.要點

  • 向第三方類中添加分類時,總應給其名稱加上你專用的前綴
  • 向第三方類中添加分類時,總應給其中的方法名加上你專用的前綴

三、勿在分類中聲明屬性

1.勿在分類中聲明屬性的原因

屬性是封裝數據的方式。盡管從技術上說,分類里也可以聲明屬性,但這種做法還是要盡量避免。原因在于,除了“class-continuation分類 ” 之 外 , 其 他分類都無法向類中新增實例變量,因此,它們無法把實現屬性所需的實例變量合成出來。

所以你要是想在分類中實現屬性就得自己進行設置該屬性的存取方法。你就可以用@dynamic或者消息轉發機制來實現其存取方法,但是還是不太提倡那樣做的。

當然,除了上述的方法可以實現設置分類中屬性的存取方法之外,還有關聯對象也可以解決在分類中不能合成實例變量的問題。就像這樣:
在這里插入圖片描述

這樣做可行,但是不太理想,要把相似的代碼寫很多遍,而且內存管理問題上容易出錯,因為我們在為屬性實現存取方法時,經常會忘記遵從其內存管理語義。

正確的做法應該是:把所有屬性定義在主接口里。類所封裝的全部數據都應該定義在主接口中,這是唯一能夠實現實例變量的地方。并且分類機制,它的目的就是用于擴展類的功能,而非封裝數據。

有時屬性可讀也可以定義在分類中,我們可以用其get方法獲取相關的信息,但是這樣的話還不如直接定義一個方法多好,用處還多,所以說,分類還是好好使用其擴展功能吧。

2.要點

  • 把封裝數據所用的全部屬性都定義在主接又里。
  • 在“class-continuation分類”之外的其他分類中,可以定義存取方法,但盡量不要定義屬性。

四、使用“class-continuation分類”隱藏實現細節

1.什么是class-continuation分類

OC動態消息系統的工作方式決定了其不可能實現真正的私有方法或者私有實例變量。那么怎么實現私有變量和私有方法呢?這就要用到特殊的“class-continuation分類”了。

“class-continuation分類”和普通的分類不同,他必須定義在其所接續的那個類的實現文件里,并且這個類沒有名字。

@interface EOCPerson ()
// Methods here
@end

這樣你就可以在其中定義你的私有方法和私有變量了,這樣有什么好處呢?公共接口里本來就能定義實例變量。不過,把它們定義在“class-continuation分類”或“實現塊”中可以將其隱藏起來,只供本類使用。這些實例變量也并非真的私有,因為在運行期總可以調用某些方法繞過此限制,不過,從一般意義上來說,他們還是私有的。此外,由于沒有聲明在公共頭文件里,所以將代碼作為程序庫的一部分來發行時,其隱藏程度更好。

2.“class-continuation分類”的合理用法

“class-continuation分類”還有一種合理用法,就是將public接口中聲明為“只讀”的屬性擴展為“可讀寫”,以便在類的內部設置其值。

就是說,你在外部.h文件中定義一個“只讀”的屬性,然后你又在“class-continuation分類”將其的“只讀”屬性改為“可讀寫”的,那么這樣下來,在外部看來他就是一個“只讀”的屬性,但是你可以在其內部自定義的設置其值了,他在內部來說就是“可讀寫”的了。

這樣做很有用,既能令外界無法修改對象,又能在其內部按照需要管理其數據。這樣,封裝在類中的數據就由實例本身來控制,而外部代碼則無法修改其值。

還有一種用法:若對象所遵從的協議只應視為私有,則可在“class-continuation分類”中聲明名,這樣就不會泄漏我們所遵從的協議

#import "EOCPerson.h"
#import "EOCSecretDelegate.h"@interface EOCPerson () <EOCSecretDelegate>
@end@implementation EOCPerson
/* ... */
@end

3.要點

  • 通過“class-continuation分類”向類中新增實例變量。
  • 如果某屬性在主接口中聲明為“只讀”,而類的內部又要用設置方法修改此屬性,那么就在“class-continuation分類”中將其擴展為“可讀寫”。
  • 把私有方法的原型聲明在“class-continuation分類”里面。
  • 若想使類所遵循的協議不為人所知,則可于“class-continuation分類”中聲明。

五、通過協議提供匿名對象

1.什么是匿名對象

若是接口背后有多個不同的實現類,而你又不想指明具體使用哪個類,那么可以考慮用這個方法——因為有時候這些類可能會變,有時候他們又無法容納于標準的類繼承體系中,因而不能以某個公共基類來統一表示。此概念通常稱為“匿名對象”。

@property (nonatomic, weak) id<EOCDelegete> delegate;

這個delegate就是“匿名的”,因為當你調用這個delegate的時候你并不知道它指的是那個類,而你卻又能使用它所指代類的方法,這就把那個類給隱藏起來了,匿名對象也是同樣的原理。

因為你可能定義很多的類,但是我們不能將它們都繼承于同一個類,并且在OC中只有id類型可以將這些類的隨便一個類都返回,所以我們在使用匿名對象的時候一定是返回的id類型。比如:我們將所有數據庫都具備的那些方法放到協議中,令返回的對象遵從此協議。

2.如何使用

先定義一個協議其中包括數據庫都有的方法:

@protocol EOCDatabaseConnection
- (void)connect;
- (void)disconnect;
- (BOOL)isConneceted;
- (NSArray *)performQuery:(NSString *)query;
@end

提供一個單例接口:

#import <Foundation/Foundation.h>@protocol EOCDatabaseConnection;@interface EOCDatabaseConnection;
+ (id)sharedInstance;
- (id<EOCDatabaseConnection>)connectionWithIdentifier: (NSString *)identifier;@end

這樣的話,處理數據庫連接的類名稱就不會暴露了,來自不同框架的那些類限制就都可以使用同一個方法來返回了,而不用對每個類都寫一個這種協議。

3.要點

  • 協議可在某種程度上提供匿名類型。具體的對象類型可以淡化成遵從某協議的id類型,協議里規定了對象所實現的方法。
  • 使用匿名對象來隱藏類型名稱(或類名 )。
  • 如果具體類型不重要,重要的是對象能夠相應(定義在協議里的)特定方法,那么可使用匿名對象來表示。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697040.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697040.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697040.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android進階(二十九) 走近 IntentFilter

文章目錄 一、什么是IntentFilter &#xff1f;二、IntentFilter 如何過濾隱式意圖&#xff1f;2.1 動作測試2.2 類別測試2.3 數據測試 一、什么是IntentFilter &#xff1f; 如果一個 Intent 請求在一片數據上執行一個動作&#xff0c; Android 如何知道哪個應用程序&#xf…

網頁數據的解析提取(XPath的使用----lxml庫詳解)

在提取網頁信息時&#xff0c;最基礎的方法是使用正則表達式&#xff0c;但過程比較煩瑣且容易出錯。對于網頁節點來說&#xff0c;可以定義id、class或其他屬性&#xff0c;而且節點之間還有層次關系&#xff0c;在網頁中可以通過XPath或CSS選擇器來定位一個或多個節點。那么&…

Maven管理項目,本地倉庫有對應的jar包,但還是報找不到

文章目錄 業務場景錯誤提示分析過程解決辦法 業務場景 settings.xml種配置了私服&#xff0c;但是有些依賴私服上沒有&#xff0c;通過同事拷貝過來的。但是用maven打包時報紅了。 錯誤提示 Idea Maven錯誤&#xff1a;was cached in the local repository, resolution will…

RecycleView結合ItemTouchHelper實現拖動排序

最近項目中需要實現對某一類條目進行拖動排序功能&#xff0c;實現技術方案就是利用ItemTouchHelper綁定RecyclerView、ItemTouchHelper.Callback來實現UI更新&#xff0c;并且實現動態控制是否開啟拖動功能。其中&#xff0c;ItemTouchHelper是Google在androidx包中添加的&…

int128的實現(基本完成)

雖然有一個聲明叫_int128但是這并不是C標準&#xff1a; long long 不夠用&#xff1f;詳解 __int128 - FReQuenter - 博客園 (cnblogs.com) 網絡上去找int128的另類實現方法&#xff0c;發現幾乎都是在介紹_int128的 然后我就自己想了個辦法&#xff0c;當時還沒學C&#xf…

Spring Boot中實現列表數據導出為Excel文件

點擊下載《Spring Boot中實現列表數據導出為Excel文件》 1. 前言 本文將詳細介紹在Spring Boot框架中如何將列表數據導出為Excel文件。我們將通過Apache POI庫來實現這一功能&#xff0c;并解釋其背后的原理、提供完整的流程和步驟&#xff0c;以及帶有詳細注釋的代碼示例。最…

關于設備連接有人云的使用及modbus rtu協議,服務器端TCP調試設置

有人云調試 調試過程問題1. 關于modbus rtu協議,實質上有三種modbus基本原理modbus 格式2. 關于modbus crc16通信校驗3. 關于在ubuntu阿里云服務器端,監聽網絡數據之調試mNetAssist之前的一個項目,再拿出來回顧下。 調試過程 先 要在有人云,用手機號注冊一個服務賬號,官網顯…

家的情感記憶:如何用壁紙講述你的墻故事?

1、方小童在線工具集 網址&#xff1a; 方小童 該網站是一款在線工具集合的網站&#xff0c;目前包含PDF文件在線轉換、隨機生成美女圖片、精美壁紙、電子書搜索等功能&#xff0c;喜歡的可以趕緊去試試&#xff01;

HarmonyOS—使用預覽器查看應用/服務效果

DevEco Studio為開發者提供了UI界面預覽功能&#xff0c;可以查看應用/服務的UI界面效果&#xff0c;方便開發者隨時調整界面UI布局。預覽器支持布局代碼的實時預覽&#xff0c;只需要將開發的源代碼進行保存&#xff0c;就可以通過預覽器實時查看應用/服務運行效果&#xff0c…

探索分布式強一致性奧秘:Paxos共識算法的精妙之旅

提到分布式算法&#xff0c;就不得不提 Paxos 算法&#xff0c;在過去幾十年里&#xff0c;它基本上是分布式共識的代名詞&#xff0c;因為當前一批常用的共識算法都是基于它改進的。比如&#xff0c;Fast Paxos 算法、Cheap Paxos、Raft 算法等。 由萊斯利蘭伯特&#xff08;L…

Spring6學習技術|AOP

學習材料 尚硅谷Spring零基礎入門到進階&#xff0c;一套搞定spring6全套視頻教程&#xff08;源碼級講解&#xff09; AOP AOP&#xff08;Aspect Oriented Programming&#xff09;是一種設計思想&#xff0c;是軟件設計領域中的面向切面編程&#xff0c;它是面向對象編程的…

AIDL的工作原理與使用示例 跨進程通信 遠程方法調用RPC

AIDL的介紹與使用 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android中用于定義客戶端和服務端之間通信接口的一種接口定義語言。它允許你定義客戶端和服務的通信協議&#xff0c;用于在不同的進程間或同一進程的不同組件間進行數據傳遞。AIDL通過…

深入探討YUV圖像處理:理論原理與OpenCV實踐

文章目錄 導言YUV模型的原理使用OpenCV處理YUV圖像1. 讀取YUV圖像2. 將YUV圖像轉換為RGB圖像3. 將RGB圖像轉換為YUV圖像 結語 導言 導言&#xff1a; 在圖像處理領域&#xff0c;YUV色彩模型因其對亮度和色度的分離而被廣泛使用&#xff0c;特別在視頻編碼和實時通信中發揮了巨…

算法項目(3)—— 從零實現KNN、樸素貝葉斯垃圾郵件分類

本文包含什么? 項目運行的方式項目代碼,自己實現KNN算法以及樸素貝葉斯算法.代碼介紹運行有問題? csdn上后臺隨時售后.項目說明 本文主要是自己從0實現KNN算法以及樸素貝葉斯算法.然后使用英文垃圾郵件數據集進行垃圾郵件分類.常見的代碼均調用sklearn庫來實現,本文自行實現…

AI推介-大語言模型LLMs論文速覽(arXiv方向):2024.01.01-2024.01.10

1.Pre-trained Large Language Models for Financial Sentiment Analysis 標題:用于金融情感分析的預訓練大型語言模型 author:Wei Luo, Dihong Gong date Time:2024-01-10 paper pdf:http://arxiv.org/pdf/2401.05215v1 摘要&#xff1a; 金融情感分析是指將金融文本內容劃分…

從零學習Linux操作系統第二十八部分 shell腳本中的執行流控制

一、什么是執行流、循環執行流 執行流&#xff1a;改變執行順序&#xff0c;使之更方便操作者 循環執行流&#xff1a;根據腳本是執行流再某一個狀態下進行循環執行&#xff0c;進行多次執行后再往下走&#xff08;for語句&#xff09; for語句 作用 為循環執行動作 for語句…

opencv判斷灰化情況

目的 先說說理論&#xff1a; 在圖像處理中&#xff0c;用RGB三個分量&#xff08;R&#xff1a;Red&#xff0c;G&#xff1a;Green&#xff0c;B&#xff1a;Blue&#xff09;&#xff0c;即紅、綠、藍三原色來表示真彩色&#xff0c;R分量&#xff0c;G分量&#xff0c;B分…

LeetCode LCR 055.二叉搜索樹迭代器

實現一個二叉搜索樹迭代器類BSTIterator &#xff0c;表示一個按中序遍歷二叉搜索樹&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 類的一個對象。BST 的根節點 root 會作為構造函數的一部分給出。指針應初始化為一個不存在…

vue實現拖拽(vuedraggable)

實現效果: 左側往右側拖動&#xff0c;右側列表可以進行拖拽排序。 安裝引用&#xff1a; npm install vuedraggable import draggable from vuedraggable 使用&#xff1a; data數據&#xff1a; componentList: [{groupName: 考試題型,children: [{componentType: danxua…

SQLite 的使用

SQLite 是一個輕量級、自包含和無服務器的關系型數據庫管理系統&#xff08;RDBMS&#xff09;&#xff0c;廣泛應用于嵌入式系統、移動應用程序和小中型網站。它易于創建、需要的配置較少&#xff0c;并且提供了用于管理和操作數據的強大功能集。本文&#xff0c;我們將帶領你…