目录
问题1: reloadData和reloadRowsAtIndexPaths:withRowAnimation不仅仅是一点不同
问题2: 说好的category代码, 为什么不走!
问题3: 代码跑到哪里去了?
问题4: 可变参数没有想象的那么美好!
问题1: reloadData和reloadRowsAtIndexPaths:withRowAnimation不仅仅是一点不同
问题描述:
在View里添加两个UIButton和一个UITableView, 效果是这个样子的:
核心代码如下:
@interface ViewController ()
@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:@""] || [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结尾的
更多文章, 请支持我的个人博客