目錄
問題1: reloadData和reloadRowsAtIndexPaths:withRowAnimation不僅僅是一點不同
問題描述:
在View里添加兩個UIButton和一個UITableView, 效果是這個樣子的:
核心代碼如下:
@interface ViewController () <UITableViewDataSource>
@property (assign, nonatomic) NSInteger count;
@end
@implementation ViewController
# pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"reuserIndentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.textLabel.text = [NSString stringWithFormat:@"cell count: [%ld]", self.count++];
}
NSLog(@"cell = [%@] text = [%@]", cell, cell.textLabel.text);
return cell;
}
@end
reloadData Button的處理是:
- (void)reloadDataButtonClicked {
[_tableView reloadData];
}
reloadIndexPath Button的處理是:
- (void)reloadIndexPathButtonClicked {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSArray *reloadIndexPaths = [NSArray arrayWithObjects:indexPath, nil];
[_tableView reloadRowsAtIndexPaths:reloadIndexPaths withRowAnimation:UITableViewRowAnimationNone];
}
那么問題來了, 請注意我問題的前提條件哦:
第一組問題:
在初始狀態下, 按一次reloadData Button, cell的顯示會變成:
A. cell count: 0
B. cell count: 1
C. cell count: 2
D. 上述答案都是忽悠人的
在初始狀態下按了一次reloadData Button, 再按一次reloadData Button, cell的顯示會變成:
A. cell count: 0
B. cell count: 1
C. cell count: 2
D. 上述答案都是忽悠人的
第二組問題:
在初始狀態下, 按一次reloadIndexPath Button, cell的顯示會變成:
A. cell count: 0
B. cell count: 1
C. cell count: 2
D. 上述答案都是忽悠人的
在初始狀態下按了一次reloadIndexPath Button, 再按一次reloadIndexPath Button, cell的顯示會變成:
A. cell count: 0
B. cell count: 1
C. cell count: 2
D. 上述答案都是忽悠人的
坦白講這個題目不適合做第一題, 因為我感覺有點"難"那~
問題2: 說好的category代碼, 為什么不走!
問題描述:
我們實現了NSString的Category如下:
#import "NSString+MyExtention.h"
@implementation NSString (MyExtention)
- (BOOL)isValidString {
if (self == nil || self == NULL) {
return YES;
}
if ([self isEqualToString:@"<null>"] || [self isEqualToString:@"null"] || [self isEqualToString:@"(null)"]) {
return YES;
} else if ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
return YES;
} else if ([[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]) {
return YES;
}
return NO;
}
@end
接著我們在ViewController.m引用這個Category來判斷NSString是否合法
#import "ViewController.h"
#import "NSString+MyExtention.h"
@interface ViewController ()
@property (nonatomic, strong) NSString *willBeCheckedString;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self test1];
[self test2];
}
- (void)test1 {
if ([_willBeCheckedString isValidString]) {
NSLog(@"Invalid String");
} else {
NSLog(@"Valid String");
}
}
- (void)test2 {
if (_willBeCheckedString == nil || [_willBeCheckedString isValidString]) {
NSLog(@"Invalid String");
} else {
NSLog(@"Valid String");
}
}
@end
問題來了, test1和test2的打印分別是什么呢?
test1的打印
A. Invalid String
B. Valid String
C. 上述答案都是忽悠人的
test2的打印
A. Invalid String
B. Valid String
C. 上述答案都是忽悠人的
鑒于問題1熱身過后, 這題還是比較easy的吧?
問題3: 代碼跑到哪里去了?
問題描述:
在ViewController的ViewDidLoad方法里, 我們加了三行打印如下
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
問題來了(問題描述這么精簡?是滴, 你沒看錯, 我也沒寫漏), 這行代碼的打印是什么呢?
按照慣例不用怕, 還是選擇題不是問答題哈(換行等額外的打印信息暫時忽略, 抓住主要問題即可)
A. 123
B. 132
C. 上述答案都是忽悠人的
問題4: 可變參數沒有想象的那么美好!
可變參數的API, 看起來很強大, 因為一次可以傳遞多個參數, 而不受任何限制
但其實并沒有想象的那么美好, 一不小心就引發調試"血案", 我們來看下面的實例化NSDictionary的例子
NSString *keyName = @"name";
NSString *keyAge = @"age";
NSString *keyNickname = @"nickname";
NSString *valueName = @"yuan";
NSString *valueAge = nil;
NSString *valueNickname = @"mumu";
NSDictionary *userInfo1 = [NSDictionary dictionaryWithObjectsAndKeys:valueName, keyName, valueAge, keyAge, valueNickname, keyNickname, nil];
NSMutableDictionary *userInfo2 = [NSMutableDictionary dictionary];
[userInfo2 setObject:valueName forKey:keyName];
[userInfo2 setObject:valueNickname forKey:keyNickname];
if ([[userInfo1 objectForKey:keyNickname] isEqualToString:[userInfo2 objectForKey:keyNickname]]) {
NSLog(@"nickname value is equal");
} else {
NSLog(@"nickname value is un-equal");
}
請問這里的打印信息是什么呢?
A. nickname value is equal
B. nickname value is un-equal
C. 你又在忽悠人了
小結
總結我遇到幾個好玩問題就到這里了, 如果你也有遇到, 歡迎發給我, 我會持續更新的
提示
問題1:
reloadData會先將所有cell都先放到復用池中, 然后再從復用池中取可以復用的cell
reloadRowsAtIndexPaths:withRowAnimation因為有cell進入和移出的動畫, 所以同時需要至少兩個可用的的cell(包括復用池中的cell)
問題2:
Objective-C是的方法調用其實是基于消息的, nil是不會接收和處理消息的
問題3:
這是一個死鎖問題, 原理詳見iOS開發 之 Queue和Thread
問題4:
可變參數是以nil或null結尾的
更多文章, 請支持我的個人博客