OC 基础 1

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 作用是什么?

  1. 向计算机(堆区)申请内存空间;
  2. 给实例变量初始化;
  3. 返回所申请空间的首地址;

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

  1. 可以在其他类中访问被@public修饰的成员变量
  2. 也可以在本类中访问被@public修饰的成员变量
  3. 可以在子类中访问父类中被@public修饰的成员变量

2、@private

  1. 不可可以在其他类中访问被@private修饰的成员变量
  2. 也可以在本类中访问被@private修饰的成员变量
  3. 不可以在子类中访问父类中被@private修饰的成员变量

3、@protected

默认情况下所有的实例变量都是protected

  1. 不可可以在其他类中访问被@protected修饰的成员变量
  2. 也可以在本类中访问被@protected修饰的成员变量
  3. 可以在子类中访问父类中被@protected修饰的成员变量

4、@package

介于public和private之间的,如果是在其他包中访问就是private,在当前代码中访问就是public.



六、静态库 & 动态库

1、静态库

  • 以 .a 和 .framework为文件后缀名。

  • 链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝。

2、动态库

  • 以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。

  • 链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用(如系统的UIKit.framework等),节省内存。

3、静态库 .a 和 framework区别:

.a 主要是二进制文件,不包含资源,需要自己添加头文件
.framework 可以包含头文件+资源信息


发布了43 篇原创文章 · 获赞 8 · 访问量 4589

猜你喜欢

转载自blog.csdn.net/weixin_45390999/article/details/104468166