前言
做過的項目中曾經有這樣的需求:貨品錄入(商品入庫),彈框彈出所有的貨品(很多),選擇其中的一個币狠,則下次彈框彈出所有貨品時不再顯示選擇了的那件貨品。當然砾层,錄入功能包括漩绵,刪除已選擇的貨品,則下次彈框彈出所有貨品時再次顯示出剛刪除的貨品
分析
-
低效率而且復雜的低級實現方式
(1) 單例一個彈框類肛炮,創(chuàng)建三個數組止吐,
第一個數組A里面保存的是全部的貨品(留作備份),
第二個數組B是一個可變的數組侨糟,當選擇一個貨品時從這個數組中移除碍扔,
第三個數組C個數跟A個數一樣,只是初始化的時候里面保存的都是空字符串@“”秕重,把選擇了的貨品名稱放到C中(在C中的下標要跟在A中的下標一樣不同,這樣方便后面刪除操作時,按C中元素按下標把其插入到B中悲幅,因為有些商品是熱門商品套鹅,需要保存其在頂端附近展示,不能放到最后)
(2) 每次返回數組B中的可用元素彈框展示即可汰具。
(3) 每當刪除一個貨品時,在A中查找到這件貨品在A中的位置(下標)菱魔,然后replace的方式留荔,用這件貨品替換掉C中對應位置上的元素,數據C的作用是記錄下 A中被選擇的貨品和它在A中的位置(下標)澜倦。
(4) 每當刪除一個選擇了的貨品時聚蝶,就在C中查找其的下標x,然后把其插入到B數組中的x位置
通過這種近乎原始的方式藻治,是可以完成入庫時碘勉,單單貨品名稱這項是實現了需求的效果了,但是實際一個貨品不單單是有名稱桩卵,它還有 數量验靡、單位倍宾、生產日期等屬性,在錄入的時候都是需要用到的胜嗓,所以我們自然我們想到了使用 Model 來把 一件貨品的這些屬性綁定在一起高职,方便我們使用。
而且這樣的方式實現也是沒有深刻理解 iOS 數組里面放的元素是什么辞州?其實數組里面放的不是 對象本身怔锌,而是指向這些對象(內存地址)的指針(其實是對象的內存地址)
Paste_Image.png
通過上面的圖,我們可以看到变过,指針里面的內容 其實是對象的內存地址埃元,指針的拷貝,其實就是把 對象的內存地址 拷貝一份到另一份內存中媚狰。
-
高效率岛杀、面向對象內存存儲本質的實現方式
(1)新建一個 數組 里面存儲 所有的 貨品 Model (每個model都有很多屬性:貨品的名稱、單位哈雏、生產日期、等) 裳瘪。這里最重要的解決問題的關鍵就是 把每個 model都設置一個 BooL屬性土浸,記錄每個 model的被選擇狀態(tài)。
(2) 每個商品的錄入部分都是一個 UITableViewCell 彭羹,我們把每個UITableViewCell 都定義一個 model屬性黄伊,在UITableViewCell 初始化賦值的時候,把 數組中對應的 model指針賦值給 UITableViewCell 的 model屬性派殷。
**(3)我們在錄入一件貨品的時候直接(五路以南是) 修改 這個 UITableViewCell 的 model值中的 BooL選中狀態(tài)值即可还最,被選擇時設置為YES,未被選擇時設置為 NO毡惜。 **
這樣就很輕巧地解決了上述需求了拓轻,而且很巧很簡單,但是必須要清楚里面的實現原理经伙。 UITableViewCell 的 model指針指向的對象其實和 數組中保存的對應下標的model指針扶叉,指向的對象是相同的一個,所以我們修改的對象其實是內存中alloc的 貨品model帕膜,修改后枣氧,其他通過指針找到它讀取的貨品model 都發(fā)生了改變
源碼實現
+ (instancetype )shareManager;
#返回所有未被選中的元素
- (NSArray *)getAllAvailableElement;
#重置所有元素的選擇狀態(tài)為NO
- (void)resetAllElement;
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#返回所有的可用元素
- (NSArray *)getAllAvailableElement;
{
NSMutableArray *allElementA = [[NSMutableArray alloc]initWithCapacity:0];
for (StorageGoodsMode *goods in _storageGoodsArray) {
if (!goods.selected) {
NSLog(@"JHHHH %@",goods.name);
[allElementA addObject:goods];
}
}
return allElementA;
}
#修改所有的model的狀態(tài)為未選中狀態(tài)
- (void)resetAllElement;
{
if (_storageGoodsArray.count==0) {
return;
}
for (StorageGoodsMode *goods in _storageGoodsArray) {
goods.selected = NO;
}
}