如何清空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,這樣既可以節省系統資源開銷,也可以防止誤向對象發送不存在的方法是引起的崩潰。