iOS面试基础知识自整理(待续)

变量

成员变量

特性:
  1. 在@interface或@implementation里声明
  2. 用于类的内部,无需与外界接触,与类的生命周期一致
  3. 由修饰符决定子类及其他类是否可以直接访问
  4. 不会生成get、set方法
修饰符
  • @public:在任何地方都能直接访问对象的成员变量
  • @private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法
  • @protected:可以在当前类及其子类对象方法中直接访问(系统默认下是用它来修饰的)
  • @package:在同一个包下就可以直接访问,比如说在同一个框架

注:在.h中成员变量的默认修饰符@protected. 在.m中成员变量的默认修饰符为@private.

属性

定义

提供了一个简单的方式来声明以及实现一个变量访问其方法

特性
  1. 以关键词@property声明,自动生成getter,setter方法(Xocde4.5以后),如没有对应的成员变量则自动生成成员变量
  2. 属性不是变量
  3. 用于与外界交互,可使用点语法访问成员变量
  4. @property 还可以出现在protocol 或者 category声明中
实现方式选项
  • @synthesize:默认实现方式,编译器期间,让编译器自动生成getter/setter方法,声明属性=变量,意思是作用于这个变量,当没有对应成员变量时会自动创建;当有自定义的存或取方法时,会屏蔽自动生成该方法;
  • @dynamic:告诉编译器,不自动生成getter/setter方法,避免编译期间产生警告;然后由自己实现存取方法或存取方法在运行时动态创建绑定:主要使用在CoreData的实现NSManagedObject子类时使用,由Core Data框架在程序运行的时动态生成子类属性
修饰符
  • atomic(原子性):默认属性修饰词,提供了多线程环境下对属性的安全访问和存取互斥,同一时刻,只有一个线程可以访问属性;但是读/写安全,并不是线程安全,例如对属性进行读写之外的操作;底层采用自旋锁;并发访问性能会比较低

  • nonatomic(非原子性):与atomic对应,一般不需要多线程支持的时候就用它,这样在并发访问的时候效率会比较高

  • getter=getterName:指定get方法,并需要实现这个方法 。必须返回与声明类型相同的变量,没有参数.相当于重新命名getter方法

  • setter=setterName:指定 set 方法,并需要实现这个方法 。带一个与声明类型相同的参数,没有返回值(返回空值)

  • readwirte:默认是readwrite,表示允许读/写操作

  • readonly:只生成getter方法,不生成setter方法,且不允许存储(KVC可修改值)

  • assgin:通常用于标量类型(简单变量 int , float , CGRect 等),assign不会使对象的引用计数加1,也就是说如果用assign去修饰一个对象,这个对象会立即被释放,重要的是assgin在被释放的时候是不会自动置为nil,还是保留对象的指针地址;另一种典型情况是用在对对象没有所有权的时候,通常是 delegate ,避免造成死循环(如果用 retain 的话会死循环);(MRC下是默认选项)

  • weak:不增加对对象的引用计数,也不持有对象,因此不能决定对象的释放。它比 assign 多了一个功能,当对象被释放自动把指针变成 nil

  • strong:默认选项(ARC下),表示持有该对象,并使引用计数+1

  • copy:复制成一个新对象,并引用计数+1;此属性只对那些实行了 NSCopying 协议的对象类型有效

深拷贝和浅拷贝

深拷贝(对象拷贝):重新申请一片内存保留这个对象,与原对象之间没有关系
浅拷贝(指针拷贝):实际上相当于引用计数+1,被拷贝的和拷贝的引用同一个对象

对象修饰类型结果
immutableObjectcopy浅拷贝拷贝
immutableObjectmutableCopy不完全深拷贝
mutableObjectcopy不完全深拷贝
mutableObjectmutableCopy不完全深拷贝

注:集合类对象虽然新开辟了内存地址,但是存放在内存上的值(也就是数组里的元素仍然指向原数组元素值,并没有另外复制一份)

子类的重定义

你可以在子类中对一个属性进行重定义,但是你必须在子类中同样重复它的所有额外属性(除了readonly和readwrite)。对于类别或者协议中的属性也是一样的—当属性可能在类别或者协议中被重定义式,属性的所有额外属性也要被完整重复。

实例变量

定义

实例变量是数据类型为类的成员变量

私有变量

定义

OC中提供了关键字@private来声明私有变量,只允许本类访问

OC 中没有绝对的私有变量,这么说基于两点原因:

  • 可修改: 通过KVC 键值编码 来修改私有成员变量的值
  • 可读取 : 通过底层runtime 获取实例变量Ivar 对应私有值

全局变量

定义

在@implementation外定义或方法中的变量,在任何源文件中都可以用

修饰词
  • ** static**:在Objective-C 的语法中声明后的static静态变量在其他类中是不能通过类名直接访问的,也称作私有全局变量;它只在程序开机初始化一次(并不是该类实例化后才初始化的)
  • extern:声明为一个外界可见的常值变量,可在其他文件中引用

局部变量

定义

写在代码块或函数中的变量为局部变量,生命周期与函数一致,系统会自动释放

方法

类方法

也称静态方法或者工厂方法

特性
  1. 以加号+开头,直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
  2. 类方法中不能访问实例变量(成员变量)

实例方法

特性
  1. 以减号-开头,只能让对象调用
  2. 对象方法能访问实例变量(成员变量)
  3. 类方法和对象方法可以同名

私有方法

oc中没有提供关键字来声明私有方法,可以通过catogry的匿名类Extension通过在一个只在类的.m文件中来声明一个只能被本类访问的方法。

构造方法

默认情况下,在 OC 中创建1个对象分为两部分(new):+alloc:分配内存空间;-init :初始化对象。用作初始化对象的成员变量。

自定义构造方法示例:

- (instancetype)initWithAge:(int)age andName:(NSString *)name;
// 实现自定义构造函数 在初始化的时候为属性赋值
- (instancetype)initWithAge:(int)age andName:(NSString *)name
{
    if (self = [super init]) {
      _age = age;
      _name = name;
  }
  return self;
}

类别

单独提出的一个主意点:类别中的属性property
类与类别中添加的属性要区分开来,因为类别中只能添加方法,不能添加实例变量。这种情况下,是不会自动生成实例变量的,必须自己实现get/set方法。匿名类别(匿名扩展)是可以添加实例变量的,非匿名类别是不能添加实例变量的,只能添加方法,或者属性(其实也是方法)。
OC的分类允许给分类添加属性,但不会自动生成getter、setter方法,不过最好还是不要使用;
如果声明了属性,在实现文件中编译器会提示用 @dynamic 属性名字 来告诉开发者自己来写属性的setter方法和getter方法,而这里实现setter和getter需要用到声关联对象(存取方法在运行时动态创建绑定)。

信号量、NSLock和synchronized

面试问题

  1. OC语言的动态性怎么解释
    答:他的对象类型和真正要调用的方法是在运行时才确定的,所以这就决定了在oc中没有绝对的私有变量和私有方法的,通过运行时机制runtime我们可以动态的去对类中所有的变量和方法动手脚

引用:

iOS成员变量和属性的区别iOS 成员变量 实例变量 属性变量IOS 成员变量,全局变量,局部变量定义,static与extern的区别iOS 修饰词 详解[爆栈热门 iOS 问题] atomic 和 nonatomic 有什么区别?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值