iOS 面试之三道题
1、定义宏实现MAX或者MIN.
- 菜鸟的答案是这样的:
#define MAX(X,Y) X>Y ? X : Y
验证:当输入MAX(1 == 3, 2)本来结果期望的是2,可实际结果却是0?
- 高手的答案是这样的:
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
到这里,或许大部分人都说没有问题了,大学的时候老师都是这么教的啊?你不能再说错了吧。错不错,不能光说不练,我们举例说明吧。
验证代码段如下:
float x = 1.5f;
float y = 2.0f;
float result = MAX(++x, y);
printf("result=%f,x=%f", result, x);
最后x和result的值都是3.5,为什么呢?MAX(++x, y) 展开后是这样的((++x) > (y) ? (++x) : (y)) x自增两次,有副作用啊!
- 大牛的答案是这样的:
#define MAX(x,y) ({ \
typeof(x) _max1 = (x); typeof(y) _max2 = (y); (void) (&_max1 == &_max2); _max1 > _max2 ? _max1 : _max2; })
经验证上面两种情况,没有问题了。
说明:这个宏的写法其实是Linux内核MAX的实现方式。说明几点,(1) typeof(x)的用途是得到x的类型信息,比如typeof(10)为int, typeof(1.2f)为double, (2)(void)(&_x == &_y);这一句的作用是判断_x和_y的类型是否一样,如果不一样的话,编译器会给出警告信息。
讲述UITableView的重用机制?
UITableView为了节约内存和高效,会为同一类的cell设置一个唯一标示符,当滑动的时候如果这个cell滑出屏幕,那么就将这个cell存起来,当有新的cell需要显示的时候先从内存中找,如果找到,就直接重用,否则重新 alloc一个。那么,接下来有2个问题:
(1)如果屏幕中间只能显示10个cell,那么滑动的时候第11个cell是否是重用的?
(2)UITableView还有其它部分需要重用吗?
然后,直接上代码吧,先是第一个问题:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_dataSource = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11"];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 64) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setSeparatorColor:[UIColor redColor]];
[self.view addSubview:_tableView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *sCellReusableIdentify = @"sCellReusableIdentify";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:sCellReusableIdentify];
if (!cell) {
static NSInteger tag = 1;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:sCellReusableIdentify];
cell.tag = tag++;
}
NSLog(@"tag:%ld", cell.tag);
return cell;
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return (SCREEN_HEIGHT) / 10;
}
运行结果截图如下:
我们发现,无论我们怎么滑动屏幕,cell的tag最大值也是11,那么第1个问题的答案也就浮出水面了。第11个cell一定也是新申请的。
第2个问题,section的title也需要重用的(在iOS6以后),代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_dataSource = @[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11"];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 64) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setSeparatorColor:[UIColor redColor]];
[self.view addSubview:_tableView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *sCellReusableIdentify = @"sCellReusableIdentify";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:sCellReusableIdentify];
if (!cell) {
static NSInteger tag = 1;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:sCellReusableIdentify];
cell.tag = tag++;
}
NSLog(@"tag:%ld", cell.tag);
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
const int numberOfSections = 10;
return numberOfSections;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *sHeaderReusableIdentify = @"sHeaderReusableIdentify";
UITableViewHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:sHeaderReusableIdentify];
if (!view) {
view = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:sHeaderReusableIdentify];
}
return view;
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return (SCREEN_HEIGHT) / 10;
}
写一个函数或者宏实现将RGB转化为一个UIColor *值.
同样是考察c语言的基本功:
#define COLOR_WITH_RGB(rgb) [UIColor colorWithRed:((float)((rgb & 0xFF0000) >> 16)) \
green:((float)((rgb & 0xFF00) >> 8)) blue:((float)((rgb & 0xFF))) alpha:1]
有问题,欢迎批评指正!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。