有关iOS面试问题总结

2017-11-07  本文已影响18人  同心圆圈

1、block可以修改外部变量吗?

在block内如何修改block外部变量引发的思考:为什么直接就可以修改全局变量?使用__block才可以修改局部变量?

 __block int a = 1;
 void (^foo)(void) = ^{
     a = 2;
 };
 foo(); //这里,a的值被修改为2

我们都知道:block不允许修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址。__block 所起到的作用就是只要观察到该变量被 block 所持有,就将“外部变量”在栈中的内存地址放到了堆中。进而在block内部也可以修改外部变量的值。

 __block int a = 1;
 NSLog(@"定义前:%p", &a);         //栈区
 void (^foo)(void) = ^{
      a = 2;
      NSLog(@"block内部:%p", &a);    //堆区
 };
 NSLog(@"定义后:%p", &a);         //堆区
 foo();

这也证实了:a 在定义前是栈区,但只要进入了 block 区域,就变成了堆区。这才是 __block 关键字的真正作用。

  NSMutableString *s = [NSMutableString stringWithString:@"Tom"];
  void (^foo)(void) = ^{
      s.string = @"Jerry"; //修改s中string成功(可以理解为s在栈区,s.tring在堆区)
      s = [NSMutableString stringWithString:@"William"];// 这时报错,不允许修改
  };
  foo();

这里的s已经由基本数据类型,变成了对象类型。block会对对象类型的指针进行copy,copy到堆中,但并不会改变该指针所指向的堆中的地址,所以在上面的示例代码中,block体内修改的实际是s指向的堆中的内容。

2、@synthesize和@dynamic是什么?用法?

在声明property属性后(@property本质 = ivar+getter+setter),有2种实现选择

dynamic告诉编译器不要自动创建setter、getter方法,由用户手动去实现,注意如果此时会找不到_(属性名)的实例对象,只能self.(属性名)。
synthesize如果你没有手动实现setter方法和getter方法,那么在编译的时候编译器会自动为你加上这两个方法。
如果没有声明,默认就是@synthesize 属性名 = _属性名;
使用场景:
synthesize 可以在需要同时实现set和get方法时声明 ;修改实例对象的名称等
dynamic 需要自己手动实现set和get方法时去声明,注意一定要去实现,不然调用set或get时会导致程序崩溃

3、自动释放池中的变量什么时候释放

自动释放池其实会在其作用域结束时释放池子,所有在池中的变量都会执行一次release操作,所以如果在池子中的变量执行过release操作后引用计数仍然大于0,那么就不会被释放,反之为0就会被释放,所以自动释放池中的变量也不一定出了池作用域后就会被释放的。
详细答案:http://blog.csdn.net/peixuan197/article/details/47318011

4、动态库和静态库的区别

详细答案:http://www.jianshu.com/p/c8366e4f9378

上一篇下一篇

猜你喜欢

热点阅读