面试题(一)
总结了网上一些常见的面试题,会慢慢的完善答案,有不对的地方多多交流
0,
1,UIView有哪些常见的属性可以直接动画
frame, bounds, center, alpha, hidden, layer, transform, contentScaleFactor
2,对于UITableViewCell的重用机制的理解,如果要自己实现可重用cell该有哪些步骤
每一个UITableView里都维护着一个cell队列,当UITableView刚加载的时候,cell队列里是没有任何数据的。dequeueResableCellWithIdentifier从字面上理解就是”出列可重用的cell",也就是根据一个标识identifier从cell队列里取出一个UITableViewCell,当然了,如果cell队列里没有此标识的cell,调用此方法的结果就是返回nil。因此,在UITableView刚加载的时候,cell队列里没有可用的cell,所以必须通过语句 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 来创建对应CellIdentifier标识的UITableViewCell实例。 [ tableView:cellForRowAtIndexPath:方法主要是根据nsindex取得一个cell ] 而当UITableView在滚动的时候导致UITableViewCell滚出手机屏幕视图的时候,程序会将这一个UITalbeViewCell实例放入此UITableView所维护的cell队列中。当UITableview中有新的UITableViewCell需要展现在手机屏幕视图上时,就会调用tableView:cellForRowAtIndexPath:方法了。
3,performSelector 只能传递两个参数,有什么替代的办法
[self performSelector:<#(SEL)#> withObject:<#(id)#> afterDelay:<#(NSTimeInterval)#>]无法传多个参数
解决方案1:把参数打包成一个VO或者数组 解决方案2:导入#import <objc/message.h>包 使用objc_msgSend(self,@selector(testObj:int:),10,40); 函数的第 1 个参数指向消息的接收者(即该方法的对象),第 2 个参数是一个选择器(即 方法),第 3 个参数是一个可变参数,是该方法的 1 个或多个参数,如果该方法没有参数,用 一个 nil 代替。 解决方案3: NSInvocation
4,NSTimer在触摸屏幕等事件时不会被触发,有什么办法让其正常触发
方法一:
-(void) viewDidLoad{ [self performSelectorInBackground:@selector(call1) withObject:nil]; } -(void) call1{ timer1 = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(doSomething) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSRunLoopCommonModes]; } -(void) call2{ // do something timer1 invalidate]; timer1 = nil; }
方法二:
- (void)viewDidAppear:(BOOL)animated { NSThread* timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(timerStart) object:nil]; [timerThread start]; } -(void)timerStart { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; timer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(method) userInfo:nil repeats:YES] retain];//一定要retain,不然timerStart执行完后,NSTimer就被释放了。 [runLoop run]; [pool release]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [timer invalidate]; }
方法三:
timer = [NSTimer timerWithTimeInterval:5.0 target:self selector:@selector(SendHeartBeat) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:heartTimer forMode:NSDefaultRunLoopMode];
5,NSProxy是干什么用的
NSProxy实现AOP方便为ios应用实现异常处理策略, 是Cocoa的根类,是个抽象类,NSProxy与NSObject一虚一实,并且它们都实现了NSObject协议。这让NSProxy的实现类能够很好地“代理”NSObject子类,并且把NSObject协议抽象出来,也让他们能够共享某些行为。实现代理模式。可以使用NSProxy的消息转发机制,来转发可由其它类的对象处理的任务,达成多重机制的目的
6,Dispatch_get_current_queue()在iOS6.0已经被放弃了,现在有什么办法可以预测当前是运行在哪个queue呢
之所以飞起的原因就是 容易造成死锁
http://www.kuqin.com/shuoit/20140102/337364.html 解释的较为详细
代替方案一:
dispatch_queue_tqueueA=dispatch_queue_create("com.yiyaaixuexi.queueA",NULL); dispatch_queue_tqueueB=dispatch_queue_create("com.yiyaaixuexi.queueB",NULL); dispatch_set_target_queue(queueB,queueA); staticintspecificKey; CFStringRefspecificValue=CFSTR("queueA"); dispatch_queue_set_specific(queueA, &specificKey, (void*)specificValue, (dispatch_function_t)CFRelease); dispatch_sync(queueB,^{ dispatch_block_tblock=^{ //dosomething }; CFStringRefretrievedValue=dispatch_get_specific(&specificKey); if(retrievedValue){ block(); }else{ dispatch_sync(queueA,block); } });
代替方案二:
voiddispatch_reentrant(void(^block)()) { staticNSRecursiveLock*lock=nil; staticdispatch_once_tonceToken; dispatch_once(&onceToken,^{ lock=[[NSRecursiveLockalloc]init]; }); [locklock]; block(); [lockunlock]; } dispatch_queue_tqueueA=dispatch_queue_create("com.yiyaaixuexi.queueA",NULL); dispatch_block_tblock=^{ //dosomething }; dispatch_sync(queueA,^{ dispatch_reentrant(block); });
7,objc的运行库是做什么用,你用过哪些函数?都是做什么用
大多数有两个用途:创建、修改、自省classes和object;消息分发
class_copyPropertyList, 获取一个类的所有属性