天天看點

如何清空view上的所有子視圖

如何清空view上的所有子視圖

本文重點講的是NSSet和NSArray的makeObjectsPerformSelector方法和enumerator方法

removeFromSuperview方法

首先來看看常用的removeFromSuperview方法,下面是蘋果官方定義:

Unlinks the receiver from its superview and its window, and removes it

from the responder chain.

譯: 把接收者(目前view)從它的父視圖移除,并删除它的響應鍊。

調用removeFromSuperview方法會将目前視圖從其父視圖移除。(注意:隻是将自己從俯視圖移除,以前總是誤以為将自己所有自視圖從俯視圖移除)是以用for…in…的方法,取到每一個subview,讓他們執行removeFromSuperView就可以達到效果

for (UIView *view in [self.view subviews]) {

        [view removeFromSuperview];
    }
           

注意:

1. 永遠不要在你的view的drawRect方法中調用removeFromSuperview;

2. removeFromSuperview的實質并不是将這個視圖從記憶體中移除,而是将一個視圖從他的父視圖上删除。計算機删除的本質是,标記删除,當你删除一個東西的時候,系統隻是将這塊記憶體做了一個标記,表示目前無人使用,但是之前視圖的記憶體位址存在。是以如果想讓視圖不存在,需要在移除之後置為nil。

makeObjectsPerformSelector

- (void)makeObjectsPerformSelector:(SEL)aSelector;  
- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument; 
           

介紹:讓數組中的每個元素 都調用 aSelector 并把 withObject 後邊的 argument 對象做為參數傳給方法aSelector

一行搞定删除子視圖

[self.view.sublayers makeObjectsPerformSelector:@selector(removeFromSuperview)];
           

帶參數方法的使用:如果一個數組arry中存儲了一組有hidden屬性的對象(假設為view),需要将數組裡所有對象的hide全部指派為真,就可以這麼寫:

[arry makeObjectsPerformSelector:@selector(setHidden:) withObject:@YES];  
           

這麼寫就相當于arry數組裡面的每一個對象都調用了setHidden方法,并且參數為YES,不用再周遊,一行代碼搞定,是不是很友善。

但是若想設定為NO的話,則無效(親測)。

[arry makeObjectsPerformSelector:@selector(setHidden:) withObject:@NO];  
           

這是因為YES和NO都為BOOL類型,設定為YES時,傳遞的為非0的指針,是以會設定 view.hidden = YES,但若設定為NO時,傳遞的仍為非0的指針,是以執行的結果仍是 view.hidden = YES。具體可看這裡。

但是可以用nil達到參數為NO的效果

[arry makeObjectsPerformSelector:@selector(setHidden:) withObject:nil];  
           

enumerator

這個方法也是周遊數組,block裡面的參數包括obj(運作的對象)、idx(下标)、stop(是否繼續周遊的标志),stop可以控制周遊何時停止,在需要停止時令*stop = YES即可(不要忘記前面的*),應該說,這個能滿足基本所有的周遊需求了,有下标,有運作的對象,還有是否繼續周遊的标志。

NSArray *xpArray = @[@"A", @"B", @"C", @"D", @"E"];

    [xpArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

        NSLog(@"%@", obj);

        if ([obj isEqualToString:@"C"]) {

            *stop = YES;
        }
    }];
           

不過反向周遊呢?蘋果提供了另外一個方法:

[xpArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOLBOOL *stop) {  
    NSLog(@"idx=%d, id=%@", idx, obj);  
}]; 
           

這個enumerateObjectsWithOptions:usingBlock:方法比前面那個方法多了一個枚舉類型的參數NSEnumerationReverse,這個參數指定了周遊的順序。

注意:這裡要補充一點,這個方法是可以修改塊簽名,當我們已經明确集合中的元素類型時,可以把預設的簽名id類型修改成已知類型,比如常見的NSString,這樣既可以節省系統資源開銷,也可以防止誤向對象發送不存在的方法是引起的崩潰。