1.5 万能指针 id

一. id

id是一种数据类型,并且是一种动态数据类型

数据类型的用途:

1. 定义变量

2. 作为函数的参数

3. 作为函数的返回值

默认情况下所有的数据类型都是静态数据类型

静态数据类型的特点:

在编译时就知道变量的类型,知道变量中有哪些属性和方法

在编译的时候就可以访问这些属性和方法

并且如果是通过静态数据类型定义变量,如果访问了不属于静态数据类型的属性和方法,那么编译器就会报错

应用场景:多态,可以减少代码量,避免调用了子类特有的方法需要强制类型转换

  1. id obj1 = [[Person alloc] init];
  2. [obj1 sleep];
  3. [obj1 test]; // Person类的私有方法
  4. id obj2 = [[Person alloc] init];
  5. [obj2 eat];
  6. [obj2 test]; // Person类的私有方法

为了避免动态数据类型引发的运行时的错误,一般情况下如果使用动态数据类型定义一个变量,在调用这个对象的方法之前会 进行一次判断,判断当前对象是否能够调用这个方法

1. 判断指定的对象是否是某一个类,或者是某一个类的子类

  1. id obj = [[Student alloc] init];
  2. if (obj isKindOfClass:[Student class]) {
  3. // 如果obj对象是Student类创建出来的或者是Student的子类创建出来的对象调用父类的eat方法
  4.   [obj eat];
  5. }

2. 判断指定的对象是否是当前指定的类的实例

  1. id obj = [[Student alloc] init];
  2. if (obj isMemberOfClass:[Student class]) {  
  3.   // 判断对象obj是否是Student类创建出来的对象,如果是调用类的对象方法    
  4.   [obj eat];
  5. }

二. new的实现原理

1. 创建对象new做了三件事情:

1>. 开辟存储空间  + alloc 方法;

2>. 初始化所有的属性(成员变量) - init 方法;

3>. 返回对象的地址

2. + alloc做了什么事情

1>. 开辟存储空间;

2>. 将所有的属性设置为0;

3>. 返回当前实例对象的地址

  1. Person *p1 = [Person alloc];

3. - init做了什么事情

1>. 初始化成员变量,但默认情况下init的实现是什么都没有做;

2>. 返回初始化后的实例对象的地址

  1. Person *p2 = [p1 init];

注: + alloc 和 - init 返回的实例对象的地址是同一个地址

三. 构造方法

在OC中init开头的方法,我们称之为构造方法

构造方法的用途: 用于初始化一个对象,让某个对象一创建出来就拥有某些属性和值

1. 重写init方法,在init 方法中初始化成员变量

1>. 必须先初始化父类,再初始化子类

2>. 必须判断父类是否初始化成功,只有父类初始化成功才能继续初始化子类

3>. 返回当前对象的地址

  1. - instancetype init
  2. {
  3.   if (self = [super init]) {
  4.       _age = 10;
  5.   }
  6.   return self;
  7. }

2. instancetyp和id的区别

instancetype == id == 万能指针 == 指向一个对象

id 在编译的时候不能判断对象的真实类型

instancetype 在编译的时候可以判断对象的真实类型

1>. id和instancetype除了一个在编译时不知道真实类型,一个在编译时知道真实类型

2>. id可以用来定义变量,可以作为返回值,可以作为形参,instancetype只能作为返回值

注:以后但凡自定义构造方法,返回值尽量使用instancetype,不要使用id

3. 自定义构造方法 (init自定义构造只用初始化自己的成员变量,父类的父类来处理)

  1. - (instacetype)initWithAge:(int)age andName:(NSString *)name
  2. {
  3.   if (self = [super init]) {
  4.     _age = age;
  5.     _name = name;
  6.   }
  7.   return self;
  8. }

// NSLog输出%@ 最好重写 - (NSString *)description;

  1. - (NSString *)description
  2. {
  3.   return [NSString stringWithFormat:@"age = %i, name = %@", _age, _name];
  4. }

4. 自定义类工厂方法

1> 类构造方法:initWith.....

  1. - (instancetype)initWithAge:(int)age andName:(NSString *)name
  2. {
  3.   if (self = [super init]) {
  4.     _age = age;
  5.     _name = name;
  6.   }
  7.   return self;
  8. }

2> 类工厂方法:类名开头.....

  1. + (instancetype)personWithAge:(int)age
  2. {
  3.    Person *p = [[self alloc] init];
  4.    p.age = age;
  5.    return p;
  6. }

四. 类的本质

五.SEL类型

1.创建一个人对象

  1. Person *p = [[Person alloc] init];

2.将age的setter方法封装成SEL

  1. BOOL b = [p respondsToSelector:sel];
  2. NSLog(@"%i", b);

3.判断Person对象方法中中是否存在 - 号开头的setAge:方法

  1. BOOL b = [p respondsToSelector:sel];
  2. NSLog(@"%i", b);

4.判断Person类方法中是否存在 + 号开头的setAge:方法

  1. b = [Person respondsToSelector:sel];
  2. NSLog(@"%i", b);

5.通过performSelector调用有参数的方法, 那么参数必须是对象类型

  1. SEL sel1 = @selector(setName:);
  2.        
  3. [p performSelector:sel1 withObject:@"jack"];
  4. NSLog(@"name = %@", p.name);

来自为知笔记(Wiz)

时间: 2024-08-27 00:56:55

1.5 万能指针 id的相关文章

id类型 万能指针 oc

id类型 id已经是关键字,以后定义变量要注意: id是万能指针:能指向.操作任何OC对象,没有*,因为它已经包含了*: Person *p = [Person new];可以用下面的来代替,只适用于OC对象: id d = [Person new]; id 你可以认为是NSObject * 因为NSObject *o = [Person new]; @property id obj;

void *:万能指针

实例 #include <string.h> #include <stdio.h> int main () { void * p; int a = 10; p = &a; printf("%d\n", *((int *)p)); return(0); } 原文地址:https://www.cnblogs.com/xumaomao/p/11992038.html

张超超OC基础回顾_05 property修饰符,id类型,instancetype。。。

一.property 如果给一个属性同时提供了getter/setter方法, 那么我们称这个属性为可读可写属性 如果只提供了getter方法, 那么我们称这个属性为只读属性 如果只提供了setter方法, 那么我们称这个属性为只写属性 如果既没有提供getter也没有提供setter方法, 那么我们称这个属性为私有属性 格式: @property(属性修饰符) 数据类型 变量名称; @property(readwrite) int age; // 可读可写的 ,不用写的 默认就是这 /* -

黑马程序员_ Objective-c 面向对象笔记详解

1)类,对象,方法 类 类名: 1) 类名的第一个字母必须是大写 2) 不能有下划线 3) 多个英文单词,用驼峰标识 类的声明和实现 类的声明 @interface 类名 : NSObject { @public 成员变量: } 方法声明; @end 类的实现 @implementation 类名 方法实现; @end 举例说明: view plaincopy //Horse类的声明 @interface Horse : NSObject { @public //使成员变量可以让外部访问 //定

黑马程序员_ 利用oc的协议实现代理模式

先说下代理模式是什么吧 定义: 为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象 而代理对象可以在客户端和目标对象之间起到中介的作用. 在看过李明杰老师的课程后,我对代理模式有了最初步的理解,虽然还很浅显 但是也明白了代理模式的 一些作用跟用法.首先使用代理模式可以降低耦合度.大大的增强了代码的弹性. 举个例子,小明想看电影,但是没时间买票 于是就拜托小强去买票 最简单的方式就是 建立一个person类(小明) 一个agent类(代理类) ag

OC脱变第四天

总结 标号 主题 内容 一 OC的私有方法 私有变量/私有方法 二 @property 概念/基本使用/寻找方法的过程/查找顺序 三 @synthesize @synthesize概念/基本使用/注意点 四 id 静态类型和动态类型/有动态类型原因/id数据类型与静态类型 五 new new方法实现原理/alloc与init 六 构造方法 重写init方法/使用注意/instancetype的作用 七 自定义构造方法 格式/继承中的构造方法 八 自定义类工厂方法 自定义类工厂方法/子父类中的类工

OC基础 04

OC 基础04 [email protected]基本概念 >[email protected]是编译器的指令 >[email protected] 用在声明文件中告诉编译器声明成员变量的的访问器(getter/setter)方法 这样的好处是:免去我们手工书写getter和setter方法繁琐的代码 @property基本使用 1.在@inteface中,用来自动生成setter和getter的声明 示例: 用@property int age; // 就可以代替下面的两行 - (int)a

C和OC的基础语法(易混淆的概念知识)

List 0. 深复制与浅复制, NSObject万能指针.id指针.instancetype区别,单例import.include.@class的区别 strong 与 weak 区别 #define  和  typedef的区别, static 与  extern 区别,@required与@optional 区 别,@private.@protected .@public.@package区别 变量的命名规则以及规范(4规则,2规范) 数据类型转换 printf与scanf,自增自减,逻辑

关情纸尾-----OC面对对象的核心语法

有点愧疚,这几个月荒废了,也浪费了很多时间. 接下来是我看的关于核心语法的一些笔记,可能不全也可能有错误,希望大家可以指出来. 一.点语法 点语法的本质是调用. 例如: Person *p = [Person new]; //赋值 p.age = 10; // 等价于[P setAge:10];调用setter //取值 int a = p.age;// 等价于[P age];调用getter 二.成员变量的作用域 @public  任何地方都能直接访问 @private 只能在当前类的对象方法