iOS回顧筆記( 02 ) -- 由九宮格布局引發的一系列“慘案”

?

iOS回顧筆記( 02 ) -- 由九宮格布局引發的一系列“慘案”

前言(扯幾句淡先)

回顧到學習UI過程中的九宮格布局時,發現當時學的東西真是不少。

這個階段最大的特點就是:知識點繁多且瑣碎

我們的目標就是要將這瑣碎的知識點靈活運用、融匯貫通,通過不同的實現方式來實現相同的功能,最后進行比較得到最好的那種方式。這個求知的過程就是我們最需要學習的,在過程中我們學會了自我思考,并且在自己的思考和比較中,我們的腦海里逐漸形成了自己的編程思想。

本文主要以九宮格購物車的實現為引子,從最基礎的實現方法層層遞進直到最完美的實現方式。代碼從起初的低效、耦合度高到后期的層層分離、MVC各模塊封裝,高內聚、低耦合,更具擴展性等方面逐步深化和擴展;經過編程思想的層層深入和代碼的步步完善最后完整的展現在用戶面前。

本文大體目錄

  • 九宮格購物車demo
  • 對應物品封裝(View的簡單封裝)
  • 數據的加載方式對比 與 演變
  • 屬性列表文件(plist)的創建和使用
  • MVC 思想的引入和介紹

九宮格購物車Demo

九宮格是我們在開發過程中對于一些有規律的UI布局常用的一種布局算法。
九宮格特點:簡單,封裝性好,可復用性高,很適合一些頁面同類型item數量動態變化UI頁面布局

下面就實現一個買書購物車

Snip20170301_3.png
基本要求和思路如下

思路:
1. 最初沒有書(刪除按鈕不可用)
2. 點擊添加就添加一本書(刪除按鈕可用)
3. 添加基本之后(提示購物車已滿,添加按鈕不可用)
4. 刪除按鈕點擊(購物車不滿的時候添加按鈕又可以使用)
5. 添加書籍按九宮格的樣式在頁面中顯示




先說說最直接的方法

// 添加書
- (IBAction)addBook:(id)sender {// 1. 創建書圖標UIImageView *bookIcon = [UIImageView new];bookIcon.image = [UIImage imageNamed:@"0"];bookIcon.frame = CGRectMake(0, 0, 50, 50);[self.shopView addSubview:bookIcon];// 2.書名UILabel *bookName = [UILabel new];bookName.frame = CGRectMake(0, 50, 50, 20);bookName.text = @"book1";bookName.textAlignment = NSTextAlignmentCenter;[self.shopView addSubview:bookName];// 3.添加到數組(分開寫好像很難明確如何添加這本書)}

這是最直接的方法來添加的一本書,這樣確實能添加一本書,但是這種直觀、死板的思想是不對的。

  • 面對這樣的動態變化的UI頁面,每次添加和刪除書籍的操作都是用戶隨機的,所以代碼每次也是根據對應的點擊來計算對應書籍要添加的位置。
  • 每本書的位置主要是和它對應的index來確定,這就涉及到“書”這個對象要每次計數,書是一個整體,所以書內部的東西應當封裝起來。
  • “書”在UI上表現是 圖標 + 書名,也就是iamgeview + label,從用戶看到的整體性上來說,每次添加和刪除同一本書也需要對 圖標 和 書名 分別計算兩次來計算和排列。這也是非常不合理的,并且很容易計算出現問題。應該根據UIView 父子控件相關特性對“書”進行封裝,添加/刪除的時候統一處理父控件,至于內部屬性都會根據父控件來自動布局,方便管理。

書的封裝

了解以上說的直接把代碼分開寫的局限性之后,現在來封裝一下“書”這個對象。

  • UI層的封裝,我們先分析UI布局:內部屬性只有 圖標(UIImagevView) 和 書名(UILabel)
  • 父控件選取原則:父控件只是承載子控件的容器,應當簡潔為主,所以選擇 UIView
// 0. 創建書UIView *book = [UIView new];book.frame = CGRectMake(0, 0, 60, 70);book.backgroundColor = [UIColor redColor];[self.shopView addSubview:book];// 1. 創建書圖標UIImageView *bookIcon = [UIImageView new];bookIcon.image = [UIImage imageNamed:@"0"];bookIcon.frame = CGRectMake(0, 0, 60, 50);[book addSubview:bookIcon];// 2.書名UILabel *bookName = [UILabel new];bookName.frame = CGRectMake(0, 50, 60, 20);bookName.text = @"book1";bookName.textAlignment = NSTextAlignmentCenter;[book addSubview:bookName];// 3.添加到數組(直接添加書這個對象)[self.books addObject:book];

這樣在創建和管理書的時候就方便多了,并且有一個數組來記錄添加書的數量,在添加和刪除的時候有計算的依據:可計算對應位置和兩個按鈕的可用情況

九宮格布局的思路和實現

書的對象已經封裝好了,我們可以以整體思維來操作它,下面就是計算位置的思路。

  • 書的數量不定,但列數是固定的,可以設置成變量 int clos = 3;
  • 每本書之間可能有一定間距,橫向間距 margin = ( width - clos * book.width)/ ( clos / 2) ;
  • 每本書的位置(x,y)可根據下圖發現規律 x = 列號 * (W + margin); y = 行號 * (H+margin)
  • 行號規律 : 行號 = index / clos ;
  • 列號規律 : 列號 = index % clos ;

Snip20170301_4.png

有了上面的鋪墊,就可以寫動態代碼了,只需要用戶 設置一個列數,知道最終有多少本書,遍歷每本書,根據書的索引來計算對應的書的位置即可。

廢話不多說了,上代碼

// 添加書
- (IBAction)addBook:(id)sender {// 設置列數為 3int clos = 3;// 設置書的寬高分別為 W HCGFloat W = 60;CGFloat H = 70;CGFloat iconH = 50;// 0. 創建書UIView *book = [UIView new];book.backgroundColor = [UIColor redColor];[self.shopView addSubview:book];// 計算書的位置// 獲得索引NSUInteger index = [self.books count];// 計算橫間距 marginCGFloat margin = (self.shopView.frame.size.width - clos * W) / (clos - 1);// 書 frame 的 XCGFloat x = (index % clos) * (W + margin);// 書 frame 的 YCGFloat y = (index / clos) * (H + margin);book.frame = CGRectMake(x, y, W, H);// 1. 創建書圖標UIImageView *bookIcon = [UIImageView new];bookIcon.image = [UIImage imageNamed:@"0"];bookIcon.frame = CGRectMake(0, 0, W, iconH);[book addSubview:bookIcon];// 2.書名UILabel *bookName = [UILabel new];bookName.frame = CGRectMake(0, iconH, W, H-iconH);bookName.text = @"book1";bookName.textAlignment = NSTextAlignmentCenter;[book addSubview:bookName];// 3.添加到數組(分開寫好像很難明確如何添加這本書)[self.books addObject:book];}

效果圖如下

Snip20170301_5.png

書數據加載方式和對比

到這里購物車里的書已經可以隨意添加了,并且可以根據用戶的點擊,無限制的添加。
如果項目需求修改了,比如變成5列了,寬高什么的也是根據項目自行修改就行。
九宮格布局的代碼已經完成了。

現在需要注意的問題是,“書”的屬性數據的添加問題,現在簡單的來說,書屬性有 :書名 + icon。

“書”的各屬性值,應該如何賦值呢?



幾種簡單數據加載方法與對比

  • 直接根據 index 來進行if判斷,逐個添加數據
    if (index == 0) {bookIcon.image = [UIImage imageNamed:@"0"];bookName.text = @"Book1";}else if(index == 1){bookIcon.image = [UIImage imageNamed:@"1"];bookName.text = @"Book2";}else if(index == 2){bookIcon.image = [UIImage imageNamed:@"2"];bookName.text = @"Book3";}...
  • 創建一個書的數組,數組存放對應的字典,作為書的屬性方法的數據源,從中取值
// 0.創建書的數據源self.books = @[@{@"icon":@"0",@"name":@"book1"},@{@"icon":@"1",@"name":@"book2"},@{@"icon":@"2",@"name":@"book3"},@{@"icon":@"3",@"name":@"book4"},];// 1.書圖標
bookIcon.image = [UIImage imageNamed:self.books[index][@"icon"]];  
// 2.書名
bookName.text = self.books[index][@"name"];
  • 進一步分離數據,將數據信息放到其他文件中,用的時候從文件中讀取
    // 獲取文件路徑NSString *books = [[NSBundle mainBundle] pathForResource:@"bookData" ofType:@"plist"];// 加載路徑中內容放到數組中_books = [NSMutableArray arrayWithContentsOfFile:books];// 1.書圖標bookIcon.image = [UIImage imageNamed:self.books[index][@"icon"]];  // 2.書名bookName.text = self.books[index][@"name"];

對于三種方法簡單的比較和點評

  • 第一種直接if判斷index的位置

    • 直接把動態判斷代碼寫到代碼中,過于死板
    • 代碼耦合性太高,及其不利于后期擴展,如果加數據簡直是惡魔
    • 一些死布局并且元素個數極少(幾個)的時候可以使用
    • 代碼重復性高,技術含量低
  • 第二種把數據代碼獨立出來放到一個數組中

    • 避免了第一種直接寫到代碼中的低效且惡心的做法
    • 代碼還是和數據耦合到一起了,如果后期修改需要修改代碼
    • 如果數據量大,及其不利于后期管理和數據的修改
    • 相比第一種有明顯的分離,是一種進步
  • 第三種代碼和數據分離,放到外部文件中

    • 徹底代碼和數據分離,耦合性低,易于擴展
    • 數據放到文件中、后期添加或者修改數據無需改動代碼、更加獨立
    • 代碼更簡潔直觀,只需關注功能和布局
    • 適合企業開發、這是一種通用方式(網絡應用更是如此)

plist文件介紹和使用

簡介

  • plist文件全稱:Property List文件,中文又叫屬性列表文件。
  • 是蘋果平臺上常用的一種資源描述類文件。
  • 它存儲的屬性一般都是Xcode里面的基本數據類型或者OC里面的對應類型(NSDictionary,NSArray,NSString等)
  • Xcode會自動進行解析成可以打開和合上的層疊格式
  • 用文本文件打開直接就是XML格式的鍵值對

plist文件的創建

plist的創建一般直接用Xcode創建,然后在里面添加對應的key和value,(幾乎沒有人會手寫plist文件)

3月-02-2017 15-05-43.gif

plist文件的使用

plist使用就和其他的文件用法一樣,先讀取目標文件的路徑在根據路徑加載到數組中。

// 獲取文件路徑NSString *books = [[NSBundle mainBundle] pathForResource:@"bookData" ofType:@"plist"];// 加載路徑中內容放到數組中_books = [NSMutableArray arrayWithContentsOfFile:books];

plist使用注意

我們自己創建plist文件的時候不能使用info/Info.plist命名

由于每次創建工程的時候,系統會自動生成一個對該項目信息進行描述的info.plist,它會記錄項目的一些包名、項目名、開發工具、版本和其他項目的基礎信息。

所以我們自己創建plist文件的時候不能使用info/Info.plist

這是為了不和系統的info.plist混淆,實際上自己創建一個info.plist文件和系統重名之后項目是運行不了的。

懶加載(lazyLoad) -- 提升性能

懶加載又叫延遲加載,由于項目運行時候很多數據用不到,可以暫時不創建,等到用的時候在創建,這樣節省系統性能。

如以上項目中,就是在添加書的方法中每次創建書籍數組

// 添加書
- (IBAction)addBook:(id)sender {self.books = @[@{@"icon":@"0",@"name":@"book1"},@{@"icon":@"1",@"name":@"book2"},@{@"icon":@"2",@"name":@"book3"},@{@"icon":@"3",@"name":@"book4"},];// 設置列數為 3int clos = 3;// 設置書的寬高分別為 W HCGFloat W = 60;CGFloat H = 70;CGFloat iconH = 50;// 0. 創建書UIView *book = [UIView new];book.backgroundColor = [UIColor redColor];

這樣其實非常耗性能,每次都要創建一個數組,然后用過一次就沒有用了,對此可以進行一個優化,對于該書籍數據其實就是一個固定數據,每次用一下,用的時候再創建,不用的時候就不管了,這里正好用懶加載最好了。

懶加載實際上就是一個get方法


// 懶加載書籍數據
- (NSMutableArray *)books
{if (_books == nil) {// 獲取文件路徑NSString *books = [[NSBundle mainBundle] pathForResource:@"bookData" ofType:@"plist"];// 加載路徑中內容放到數組中_books = [NSMutableArray arrayWithContentsOfFile:books];}return _books;
}// 使用的時候,直接用數組就行
bookIcon.image = [UIImage imageNamed:self.books[index][@"icon"]];
bookName.text = self.books[index][@"name"];

MVC 思想的介紹和引入

以上的小Demo,已經告一段落了,可以實現把文件中書籍數據,按九宮格的布局添加到購物車中,也可以一一刪除。

思考

還有什么可以改進的嗎?
數據就這樣存放到數組中就完美了嗎?
每次用書的數據的時候,直接從數組總取出來確實方便,但是這樣真的足夠完美嗎?
現在的所有代碼幾乎都在一個文件中,如果項目大了也這樣寫嗎?
上面把對應的數據加載方式分離到文件中了,其他的業務邏輯能不能也分離一下,能不能讓項目的結構更加清晰?

待著這些思考,答案是肯定的,項目的代碼還是非常耦合的,并且有個致命的缺點。

  • 每次從數組中取書的信息時候都自己寫key值,self.books[index][@"icon"] 如果這個“icon“手誤寫錯,編輯器一點提示也沒有
  • 如果書有很多屬性,每次手寫key值很頭痛,并且代碼看起來很糟

所以我們需要一種新的方式:因為書是一個對象,可以把它封裝成對象,它用有自己的各種屬性和方法。這樣做有幾點好處:

  • 便于管理,在使用的時候直接調用屬性的get方法就行。
  • 系統會自動提示get方法,安全性高不會出錯,如果寫錯系統會報錯。
  • 代碼封裝性好,書就是書,而不是每次到數組中去取字典根據對應的key來取值
  • 擴展性好,如果日后需要添加新的屬性和方法,直接在”書“類中加就行

MVC介紹

經過上面的分析,可以確定的是書應該獨立封裝起來保存數據,頁面邏輯也應該單獨管理,至于ViewController恰好就是兩者的橋梁。這樣的設計模式就是MVC

  • M : (Model)數據模型,用來存儲和保存數據
  • V : (View)UI視圖,用來展示給用戶看的頁面,一些復雜的頁面要封裝起來放到里面單獨管理。
  • C: (Controller)控制器,是兩者的橋梁,主要用來處理業務邏輯。

使用MVC模式可以很好的簡化項目代碼,對不同的模塊進行封裝,降低耦合性,擴展性也會得到提高,MVC是企業開發常用的設計模式。

MVC的分層封裝和使用

經過分析可知,在此小項目中,書和展示的書的UI和ViewController對應MVC的關系:

  • 書 -- Model:用來封裝書的各種屬性信息和方法
  • 書UI -- View:封裝書這個小表象,用于展示給用戶看
  • ViewController -- Controller:用來處理整體的業務邏輯,優化代碼



廢話不多說了,上各層的代碼

  • 下面是書的代碼封裝:存儲書的數據和方法

頭文件 XYBook.h@interface XYBook : NSObject// 書圖標
@property (nonatomic, copy) NSString *icon;
// 書名字
@property (nonatomic, copy) NSString *name;// 對象方法,返回自己對象
- (instancetype)initWithDict:(NSDictionary *)dict;
// 類方法,返回自己對象
+ (instancetype)bookWithDict:(NSDictionary *)dict;
@end#import "XYBook.h"@implementation XYBook- (instancetype)initWithDict:(NSDictionary *)dict
{if (self = [super init]) {[self setValuesForKeysWithDictionary:dict];}return self;
}+ (instancetype)bookWithDict:(NSDictionary *)dict
{return [[self alloc] initWithDict:dict];
}
@end
  • 書的UI的封裝:集中布局,減少控制器代碼,優化控制器邏輯

XYBookView.h 頭文件#import <UIKit/UIKit.h>
@class XYBook;@interface XYBookView : UIView// 只放一個數據屬性用來賦值,內部布局,放到.m 中自己管,不暴露給外界
@property (nonatomic, strong) XYBook *book;@end實現文件 .m文件
#import "XYBookView.h"
#include "XYBook.h"@interface XYBookView ()@property (nonatomic, weak) UIImageView *icon;@property (nonatomic, weak) UILabel *label;@end@implementation XYBookView- (instancetype)initWithFrame:(CGRect)frame
{if (self = [super initWithFrame:frame]) {// 1. 創建書圖標UIImageView *icon = [UIImageView new];self.icon = icon;[self addSubview:self.icon];// 2.書名UILabel *bookName = [UILabel new];bookName.textAlignment = NSTextAlignmentCenter;self.label = bookName;[self addSubview:self.label];}return self;
}// 重寫布局
- (void)layoutSubviews
{[super layoutSubviews];CGSize size = self.frame.size;self.icon.frame = CGRectMake(0, 0, size.width , size.height * 0.7);self.label.frame = CGRectMake(0, size.height * 0.7, size.width, size.height *(1 - 0.7));}// 設置書的屬性
- (void)setBook:(XYBook *)book
{_book = book;self.icon.image = [UIImage imageNamed:book.icon];self.label.text = book.name;
}
@end
  • 控制器:不管細節,專注處理邏輯

// 懶加載數據源
- (NSMutableArray *)books
{if (_books == nil) {_books = [NSMutableArray array];// 獲取文件路徑NSString *books = [[NSBundle mainBundle] pathForResource:@"bookdata" ofType:@"plist"];// 加載路徑中內容放到數組中NSMutableArray *arrayM = [NSMutableArray arrayWithContentsOfFile:books];for (NSDictionary *dict in arrayM) {XYBook *book = [XYBook bookWithDict:dict];[_books addObject:book];}}return _books;
}// 添加書
- (IBAction)addBook:(id)sender {// 設置列數為 3int clos = 3;// 設置書的寬高分別為 W HCGFloat W = 60;CGFloat H = 70;// 0. 創建書XYBookView *bookView = [XYBookView new];bookView.backgroundColor = [UIColor redColor];// 計算書的位置// 獲得索引NSUInteger index = [self.shopView.subviews count];// 計算橫間距 marginCGFloat margin = (self.shopView.frame.size.width - clos * W) / (clos - 1);// 書 frame 的 XCGFloat x = (index % clos) * (W + margin);// 書 frame 的 YCGFloat y = (index / clos) * (H + margin);bookView.frame = CGRectMake(x, y, W, H);[self.shopView addSubview:bookView];// 給書的UI設置數據bookView.book = self.books[index];[self checkState];self.removeBtn.enabled = YES;
}// 移除書
- (IBAction)removeBook:(id)sender {[[self.shopView.subviews lastObject] removeFromSuperview];[self checkState];self.addBtn.enabled = YES;
}

以上就是對于本Demo的最終MVC封裝版
不同部分各司其職,負責自己的模塊
項目的健壯性和封裝性也也到了對應的提高



小記

一個簡單的九宮格購物車的小Demo,真是麻雀雖小五臟俱全。

關于這個項目的完整代碼,歡迎私聊或評論找我要,如果文章有任何問題或有其他技術問題,歡迎隨時和我交流。

最后放一張項目效果圖
2017-03-02 17.47.23.gif

?

轉載于:https://www.cnblogs.com/xiaoyouPrince/p/6494710.html

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

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

相關文章

【GlobalMapper精品教程】007:如何加載谷歌衛星影像?

“Global Mapper支持所有OGC標準數據源類型,例如用于流式柵格地圖的WMS / WMTS,用于矢量數據集的WFS和用于為指定區域下載單個數據文件的WCS。預先切片的圖像和地形數據集也可以使用OSM(OpenStreetMaps)、TMS(Tiled Map Service)和Google Maps瓦片架構支持。您只需要選擇適當…

LVS/keepalived配置

LVS/DR keepalived配置注意&#xff1a;前面雖然我們已經配置過一些操作&#xff0c;但是下面我們使用keepaliave操作和之前的操作是有些沖突的&#xff0c;所以若是之前配置過DR&#xff0c;請首先做如下操作&#xff1a;dr上執行&#xff1a;$ipv -Cifconfig eth0:0 down前…

Mysql清空表(truncate)與刪除表中數據(delete)的區別

2019獨角獸企業重金招聘Python工程師標準>>> 為某基于wordpress搭建的博客長久未除草&#xff0c;某天升級的時候發現已經被插入了幾萬條垃圾留言&#xff0c;如果一條條刪除那可真是累人的活。遂考慮直接進入mysql直接清空表或者刪除表中數據。 本文記錄一下這2種操…

[轉]云原生到底是什么?

&#x1f4cb; 個人簡介 &#x1f496; 作者簡介&#xff1a;大家好&#xff0c;我是阿牛&#x1f61c; &#x1f4dd; 個人主頁&#xff1a;館主阿牛&#x1f525; &#x1f389; 支持我&#xff1a;點贊&#x1f44d;收藏??留言&#x1f4dd; &#x1f4ac;格言&#xf…

【GlobalMapper精品教程】008:如何根據指定區域(shp、kml、cad)下載衛星影像?

本文講解在Globalmapper中根據指定的范圍(shp、kml、cad等格式)進行在線衛星影像的下載方法。 文章目錄 一、根據shp范圍下載谷歌影像1. 加載谷歌影像2. 加載shp矢量范圍3. 根據范圍導出影像二、根據kml范圍下載谷歌影像1. 生成研究區范圍kml2. 根據kml范圍下載影像三、根據CAD…

膛目結舌的代碼技巧!一看就是冷暴力~~~~

你見過哪些令你膛目結舌的代碼技巧&#xff1f; 代碼世界有很多令人大呼小叫的技巧&#xff01;有的代碼像魔術師一樣巧妙地隱藏了自己&#xff0c;有的像魔法師一樣讓你眼花繚亂&#xff0c;還有的像瑜伽大師一樣靈活自如。它們讓我們驚嘆不已&#xff0c;讓我們覺得自己仿佛置…

聯合線程

聯合線程實際上就是把多線程又聯合成了一個線程&#xff0c;但這里還是要比單線程靈活很多&#xff0c;比如說&#xff0c;我可以讓一個線程到運行到某一個條件再聯合其他線程。當前線程與其他線程聯合在一起&#xff0c;又一種讓出cpu&#xff0c;而且直到別個線程運行完&…

Kafka學習征途:不再依賴ZK的KRaft

【Kafka】| 總結/Edison Zhou1新的KRaft架構在Kafka 2.8之前&#xff0c;Kafka重度依賴于Zookeeper集群做元數據管理和集群的高可用&#xff08;即所謂的共識服務&#xff09;。在Kafka 2.8之后&#xff0c;引入了基于Raft協議的KRaft模式&#xff0c;支持取消對Zookeeper的依賴…

探索java世界中的日志奧秘

java日志簡單介紹 對于一個應用程序來說日志記錄是必不可少的一部分。線上問題追蹤&#xff0c;基于日志的業務邏輯統計分析等都離不日志。JAVA領域存在多種日志框架&#xff0c;目前常用的日志框架包括Log4j&#xff0c;Log4j 2&#xff0c;Commons Logging&#xff0c;Slf4j&…

nginx的負載均衡集群

針對域名:vim /usr/local/nginx/conf/vhosts/lb.conf //自定義名稱upstream xrc { //別名server 192.168.0.1:80 weight2; //包含的主機server,負載均衡里面的機器server 192.168.0.2:80 weight1; //權重weight}server {li…

英語名言警句100句

1、寧為百夫長&#xff0c;勝作一書生。——楊炯 Better be a centurion than a scholar. 2、我是閑暇為所有中最的。——蘇格拉底 I am the most leisure of all. 3、立志不堅&#xff0c;終不濟事。——朱熹 If you are not determined, you will not help. 4、人學始知道&am…

RabbitMQ細說之開篇

前言關于消息中間件的應用場景&#xff0c;小伙伴們應該都耳熟能詳了吧&#xff0c;比如經常提到的削峰填谷、分布式事務、異步業務處理、大數據分析等等&#xff0c;分布式消息隊列成為其中比較關鍵的橋梁&#xff0c;也就意味著小伙伴們得掌握相關技能&#xff1b;當下相對比…

【Java】五種常見排序之-----------冒泡排序

冒泡排序&#xff1a; 原理: 將關鍵字較小的值不斷地上浮&#xff0c;將關鍵字值較大的不斷下沉&#xff1b;時間復雜度&#xff1a;O(n^2)空間復雜度&#xff1a;最優&#xff08;即已經排好序&#xff09;為0&#xff0c;平均空間復雜度為O(1);核心代碼&#xff1a;for(int i…

混戰的低代碼江湖,如何區分「李逵」和「李鬼」?

作者&#xff1a;APICloud 創始人劉鑫 這兩年&#xff0c;無論是資本層面&#xff0c;還是企業IT部門的關注&#xff0c;“低代碼”都是絕對的熱點。互聯網圈也似在一夜之間冒出了各種各樣的低代碼公司。 到底什么是低代碼&#xff1f;低代碼是新技術么&#xff1f;低代碼開發能…

關于捕獲鍵盤信息的processDialogkey方法2--具體應用

自定義控件里的keydown方法無法捕獲所有的按鍵消息的處理方法1&#xff08;自定義控件里的keydown方法無法獲取的鍵值如上下左右鍵等&#xff09; 處理辦法具體如下&#xff1a; 1、首先在自定義控件UserControl1中重寫ProcessDialogKey方法 自定義控件UserControl1中重寫Proce…

指針

指針 題目一&#xff1a; 計算兩數的和與差 本題要求實現一個計算輸入的兩數的和與差的簡單函數。 函數接口定義&#xff1a; void sum_diff( float op1, float op2, float psum, float pdiff ); 其中op1和op2是輸入的兩個實數&#xff0c;psum和pdiff是計算得出的和與差。 裁判…

【MapGIS精品教程】006:MapGIS根據經緯度計算各比例尺圖幅編號

己知某點的經緯度或圖幅西南圖廓點的經緯度,計算該點所在圖幅號。 例題一:某點的經度為11433′45″,緯度為3922′30″,計算所在1:250000圖幅的編號。 文章目錄 1. 公式計算編號的方法2. 軟件計算編號的方法1. 公式計算編號的方法 求解過程: 第一步,利用下列公式計算其所…

寫出一個緩存系統的偽代碼001

/*** 寫出一個緩存系統的偽代碼*/ public class CacheDemo {private Map<String, Object> map new HashMap<String, Object>();public static void main(String[] args) {// TODO Auto-generated method stub} public synchronized Object getData(String key)…

分析完百年飛機空難數據,我發現了這幾條“保命”小秘訣

來 源&#xff5c;Giao數據 數 據 | YaJie 文 章 | 張子豪,YaJie 本文爬取了飛機失事網1908-2020年空難相關數據&#xff0c;包括空難發生次數、機組和乘客的死亡人數與死亡率、不同季節的空難發生次數、空難相關文本的關鍵詞、空難高發地、空難高發航空公司、空難高發機型以…

用 QuestPDF操作生成PDF更快更高效!

QuestPDFQuestPDF是一個開源的工具庫&#xff0c;可以在.NET或者.Net Core中生成pdf文檔它提供了一個布局引擎&#xff0c;設計時考慮到了完整的分頁支持以及靈活性要求&#xff01;比市面上常見的Aspose和iTextSharp好用太多了&#xff01;GitHub地址安裝Install-Package Ques…