OC 基础 1
文章目录
一、数据类型
1、id 类型
-
id类型:是一个独特的数据类型,可以存放任何数据类型的对象,也可以转换为任何数据类型,可以指向任意类型的对象(具有运行时特性)。
在内部处理上,这种类型被定义为 指向对象的指针,实际上是一个指向这种对象的实例变量的指针;
2、nil , Nil ,NULL和NSNULL的区别
- nil 是一个实例对象值;如果我们要把一个对象设置为空的时候,就用nil
- Nil 是一个类对象的值;如果我们要把一个 class 的对象设置为空的时候,就用Nil
- NULL 指向基本数据类型的空指针(C语言的变量的指针为空)
- NSNull 是一个对象,它用在不能使用 nil 的场合。
3、id 和 instancetype的区别
id
可以作为方法的返回
以及参数类型
,也可以用来 `定义变量·instancetype
只能作为 函数或者方法的返回值- instancetype 对比 id 的好处就是: 能精确的 限制返回值的具体类型
4、id 和 NSObject 的区别
- NSObject 和 id 都可以指向任何对象;
- NSObject 对象会在编译时进行检查,需要强制类型转换
- id 类型不需要编译时检查,不需要强制类型转换
5、NSInteger 和int 有什么区别
- 在32位操作系统时候, NSInteger 等价于 int,即32位
- 在64位操作系统时候, NSInteger 等价于 long,即64位
二、对象创建
1、New 作用是什么?
- 向计算机(堆区)申请内存空间;
- 给实例变量初始化;
- 返回所申请空间的首地址;
2、alloc init 和 new 的区别
new 与 alloc&init 的区别只剩下是,显示调用 还是隐式调用 init 的问题了。
在分配内存空间的时候,alloc相比于new 来说会使用 default_zone
。
从开放的objc运行时源码中的旧 Object 对象一窥 NSObject 的 new 实现。
+ new{
id newObject = (*_alloc)((Class)self, 0);
Class metaClass = self->isa;
if (class_getVersion(metaClass) > 1){
return [newObject init];
}else{
return newObject;
}
}
//而 alloc/init 像这样:
+ alloc{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
}
- init{
return self;
}
3、initialize方法如何调用,以及调用时机
- 当类第一次收到消息的时候会调用类的initialize方法
- 是通过 runtime 的消息机制 objc_msgSend(obj,@selector()) 进行调用的
- 优先调用分类的 initialize, 如果没有分类会调用 子类的,如果子类未实现则调用 父类的
4、load、initialize方法的区别什么?它们在category中的调用的顺序?以及出现继承时他们之间的调用过程?
- load 是类加载到内存时候调用, 优先父类->子类->分类
- initialize 是类第一次收到消息时候调用,优先分类->子类->父类
- 同级别和编译顺序有关系
- load 方法是在 main 函数之前调用的
https://www.jianshu.com/p/b0ebd656eb75
三、#include、#import、@class的区别
在C 语言中, 我们使用 #include
来引入头文件,如果需要防止重复导入需要使用
#ifndef...
#define...
#endif
在OC语言中, 我们使用#import
来引入头文件,可以防止重复引入头文件,可以避免出现头文件递归引入的现象。
@class
仅用来告诉编译器,有这样一个类,编译代码时,不报错,不会拷贝头文件.
如果需要使用该类或者内部方法需要使用 #import
导入
四、成员变量、实例变量、属性变量
@interface MyViewController :UIViewControlle
{
UIButton *yourButton;
int count;
id data;
}
@property (nonatomic, strong) UIButton *myButton;
@end
-
成员变量:定义在
{}
号中的变量。 所以yourButton、count、data都是成员变量。成员变量用于类内部,无需与外界接触的变量。因为成员变量不会生成set、get方法,所以外界无法与成员变量接触。
-
实例变量:成员变量中,数据类型是一个类 的变量。
{ }
中 的yourButton 和 data 就是实例变量,count 则不是。id 是OC特有的类,本质上讲id等同于(void *)
。所以id data 属于实例变量。实例变量本质上就是成员变量,也是类内部使用的,无需与外部接触的变量,这个也就是所谓的类私有变量。
-
根据 成员变量的私有性,为了方便访问,所以就有了属性变量。
属性变量的好处就是允许让其他对象访问到该变量(因为属性创建过程中自动产生了set 和get方法)。当然,你可以设置只读或者可写等,设置方法也可自定义。所以,属性变量是用于与其他对象交互的变量。
五、变量的修饰符 及作用范围
1、@puplic
- 可以在其他类中访问被@public修饰的成员变量
- 也可以在本类中访问被@public修饰的成员变量
- 可以在子类中访问父类中被@public修饰的成员变量
2、@private
- 不可可以在其他类中访问被@private修饰的成员变量
- 也可以在本类中访问被@private修饰的成员变量
- 不可以在子类中访问父类中被@private修饰的成员变量
3、@protected
默认情况下所有的实例变量都是protected
- 不可可以在其他类中访问被@protected修饰的成员变量
- 也可以在本类中访问被@protected修饰的成员变量
- 可以在子类中访问父类中被@protected修饰的成员变量
4、@package
介于public和private之间的,如果是在其他包中访问就是private,在当前代码中访问就是public.
六、静态库 & 动态库
1、静态库
-
以 .a 和 .framework为文件后缀名。
-
链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝。
2、动态库
-
以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。
-
链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用(如系统的UIKit.framework等),节省内存。
3、静态库 .a 和 framework区别:
.a 主要是二进制文件,不包含资源,需要自己添加头文件
.framework 可以包含头文件+资源信息