zoukankan      html  css  js  c++  java
  • IOS_OC_id ,NSObject, id<NSObject>差别

    我们常常会混淆下面三种申明(我是没有留意过):
        1. id foo1;
        2. NSObject *foo2;
        3. id<NSObject> foo3;

        第一种是最经常使用的,它简单地申明了指向对象的指针,没有给编译器不论什么类型信息,因此,编译器不会做类型检查。但也由于是这样,你能够发送不论什么信息给id类型的对象。这就是为什么+alloc返回id类型,但调用[[Foo alloc] init]不会产生编译错误。

        因此,id类型是执行时的动态类型,编译器无法知道它的真实类型,即使你发送一个id类型没有的方法,也不会产生编译警告。

        我们知道,id类型是一个Objective-C对象,但并非都指向继承自NSOjbect的对象,即使这个类型和NSObject对象有非常多共同的方法,像retain和release。要让编译器知道这个类继承自NSObject,一种解决的方法就是像第2种那样,使用NSObject静态类型,当你发送NSObject没有的方法,像length或者count时,编译器就会给出警告。这也意味着,你能够安全地使用像retain,release,description这些方法。

        因此,申明一个通用的NSObject对象指针和你在其他语言里做的类似,像java,但其他语言有一定的限制,没有像Objective-C这样灵活。并非全部的Foundation/Cocoa对象都继承息NSObject,比方NSProxy就不从NSObject继承,所以你无法使用NSObject*指向这个对象,即使NSProxy对象有release和retain这种通用方法。为了解决问题,这时候,你就须要一个指向拥有NSObject方法对象的指针,这就是第3种申明的使用情景。

        id告诉编译器,你不关心对象是什么类型,但它必须遵守NSObject协议(protocol),编译器就能保证全部赋值给id类型的对象都遵守NSObject协议(protocol)。这种指针能够指向不论什么NSObject对象,由于NSObject对象遵守NSObject协议(protocol),并且,它也能够用来保存NSProxy对象,由于它也遵守NSObject协议(protocol)。这是很强大,方便且灵活,你不用关心对象是什么类型,而仅仅关心它实现了哪些方法。

        如今你知道你要用什么类型了不?

        假设你不须要不论什么的类型检查,使用id,它常常作为返回类型,也常常常使用于申明代理(delegate)类型。由于代理类型通常在执行时,才会检查是否实现了那些方法。

        假设真的须要编译器检查,那你就考虑使用第2种或者第3种。非常少看到NSObject*能正常执行,但id无法正常执行的。使用协议(protocol)的长处是,它能指向NSProxy对象,而更经常使用的情况是,你仅仅想知道某个对象遵守了哪个协议,而不用关心它是什么类型。
  • 相关阅读:
    使用事件模式(Event API)读取Excel2007(.xlsx)文件
    rocketMq消息的发送和消息消费
    Java 七牛云存储与下载
    Spring boot + Jpa + Maven + Mysql 初级整合
    Spring+SpringMvc+Hibernate整合记录
    Mybatis-Generator自动生成代码
    idea spring+springmvc+mybatis环境配置整合详解
    Linux下安装redis
    SpringMvc的基础配置<一>
    JAVA从本机获取IP地址
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4236368.html
Copyright © 2011-2022 走看看