面试试题

//5
//    NSLog(@"1");
//    dispatch_sync(dispatch_get_main_queue(), ^{
//        NSLog(@"2");
//    });
//    NSLog(@"3");// 结果是1
    //6
//    NSMutableArray * arrayy = [[NSMutableArray array]retain];
//    NSString * string = [NSString stringWithFormat:@"test"];
//    [string retain];
//    [arrayy addObject:string];
//    NSLog(@"%ld",(unsigned long)[string retainCount]);
//    [string retain];
//    [string release];
//    [string release];
//    NSLog(@"%ld",(unsigned long)[string retainCount]);
//    [arrayy removeAllObjects];
//    NSLog(@"%ld",(unsigned long)[string retainCount]);
    //结果是3.2.1
    //8
//    NSMutableArray * array2 = [array copy];
//    [array2 addObject:@"abc"];
//    NSLog(@"%@",array2);// 结果是nil
    //Son * son = [[Son alloc]init];// 结果是:Son,Son
    //4
    //NSLog(@"%@",array);//nil

 如何创建一个线程,要求可以一直工作,不会执行一次就结束。

- (void)viewDidLoad  
{  
    [super viewDidLoad];  
    // Do any additional setup after loading the view, typically from a nib.  
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadFunc) object:nil];  
    [thread start];  
}  
static bool over = NO;  
- (void)threadFunc  
{  
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];  
    while (YES) {  
        @synchronized(name){  
            name = @"Frank";  
            [NSThread sleepForTimeInterval:2];  
            if ([NSThread isMultiThreaded]) {  
                NSLog(@"%@ isMultiThreaded",name);  
            }  
            if (over) {  
                break;  
            }  
        }  
    }  
    [pool release];  
}  

16.结束一个线程:

a)break;

    b)[thread cancel]

 17字符串地址

 NSString *s = @"123";//0x100004248
        NSString *s1 = @"123";//0x100004248
        NSString * s2 = [NSString stringWithFormat:@"123"];//0x33323135
        NSString *s3 = [[NSString alloc]initWithFormat:@"123"];//0x33323135
        NSLog(@"s=%p--s1=%p--s2=%p---s3=%p",s,s1,s2,s3);

 

1.刷新UI为什么在主线程中执行

1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新
 
2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

2.UIView 与UILayer 的关系

它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等,实际上内部都是在访问它所包含的CALayer的相关属性。

3.autorelease 在什么时候释放

4、autorelease何时释放?

 

       对于autorelease pool本身,会在如下两个条件发生时候被释放(详细信息请参见第5条)

 

1)、手动释放Autorelease pool

 

2)、Runloop结束后自动释放

 

       对于autorelease pool内部的对象在引用计数的retain == 0的时候释放。release和autorelease pool 的 drain都会触发retain--事件。 

5、autorelease释放的具体原理是什么?

 

       要搞懂具体原理,则要先要搞清楚autorelease何时会创建。

 

       我们的程序在main()调用的时候会自动调用一个autorelease,然后在每一个Runloop, 系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的 Autorelease pool(main()里的autorelease)会被销毁,这样这个pool里的每个Object会被release。

 

       可以把autorelease pool理解成一个类似父类与子类的关系,main()创建了父类,每个Runloop自动生成的或者开发者自定义的autorelease pool都会成为该父类的子类。当父类被释放的时候,没有被释放的子类也会被释放,这样所有子类中的对象也会收到release消息。

 

       那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 一个鼠标事件,键盘按下(MAC OSX),或者iphone上的触摸事件,异步http连接下后当接收完数据时,都会是一个新的Runloop。

 

       一般来说,消息循环运行一次是毫秒级甚至微秒级的,因此autorelease的效率仍然是非常高的,确实是一个巧妙的设计。 

 

4.使用蓝牙传送大批量数据

5.三个类别定义相同的方法,在调用的时候会是什么情况。

6.performSelector 在主线程中调用还是在子线程中调用,为什么

1、performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。如果imageDownloader:didFinishWithImage:image:不存在,那么直接调用 在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃);Cocoa支持在运行时向某个类添加方法,即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用。所以有时候如果使用了performSelector,为了程序的健壮性,会使用检查方法

- (BOOL)respondsToSelector:(SEL)aSelector;

posted @ 2016-03-14 20:45  张凯泽  阅读(240)  评论(0编辑  收藏  举报