iOS 面试之三道题

来源:互联网 发布:免费的自己的域名邮箱 编辑:程序博客网 时间:2024/06/07 02:09

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的类型是否一样,如果不一样的话,编译器会给出警告信息。

2、讲述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;}

3、写一个函数或者宏实现将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]

有问题,欢迎批评指正!

1 1
原创粉丝点击