第一条:了解Objective-C语言的起源

Objective-C使用的消息结构而非函数调用。

Objective-C的重要工作都由“运行组件(runtime component)”而非编译器来完成。使用Objective-C的面向对象特性所需的全部数据结构以及函数都在运行期组件里面。需要明白:Objective-C语言中的指针是用来指示对象的。想要声明一个变量,令其指向某个对象,可用以下语法:

   NSString *someString = @"The string";

这种语法基本上是照搬C语言的,它声明了一个名为someString的变量,其类型是NSString*。也就是说,此变量为指向NSString的指针。所有Objective-C语言的随想都必须这样声明,因为对象所占内存总是分配在“堆空间”(heap space)中,而绝不会分配在“栈”(stack)上。不能在栈中分配Objective-C对象:

   NSString stackString;

someString变量指向分配在堆里面的某块内存,其中含有一个NSString对象。也就是说,如果再创建一个变量,令其指向同一地址,那么并不拷贝该对象,只是这两个变量会同时指向此对象:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *name = @"Scott";
NSString *nickName = name;
NSLog(@"name's address is:%p",name);
NSLog(@"nickName's address is:%p",nickName);
}
return 0; }

输出的结果是:

2015-07-26 15:20:06.905 Test52[5631:1767824] name's address is:0x100001038
2015-07-26 15:20:06.905 Test52[5631:1767824] nickName's address is:0x100001038

我们会发现,他们其实指向的是同一块内存。其中,只有一个NSString的实例,然而有两个变量指向此实例。这两个变量都是NSString* 型,这说明当前“栈帧(stack frame)”里面分配了两块内存,每块内存的大小都能容下一枚指针(在32位架构的计算机上是4字节,64位计算机上是8个字节)。这两块内存里的值都是一样,就是NSString实例的内存地址。



此图片内存布局演示了一个 分配在堆中的NSString实例,有两个分配在栈上的指针指向该实例。

分配在堆中的内存必须直接管理,而分配在栈上用于保存变量的内存则会在栈帧弹出时自动清理。

Objective-C将堆内存管理抽象出来了。不需要malloc和free来分配或者释放对象所占内存。Objective-C运行期环境把这部分工作抽象为一套内存管理架构,明叫“引用计数”。

在Objective-C代码中,有事会遇到定义里不含* 的变量,他们可能会使用“栈空间”(stack space)。这些变量所保存的不是Objective-C对象。比如CoreGraphics框架中的CGRect:

CGRect frame;
frame.origin.x = 0.0f;
frame.origin.y =10.0f;
frame.size.width = 100.0f;
frame.size.height = 150.0f;

CGRect是C结构体,其定义为:

struct CGRect {
CGPoint origin;
CGSize size;
}
typedef struct CGRect CGRect;

整个系统框架都在使用这种结构体,因为如果改用Objective-C对象来做的话,性能会受影响。与创建结构体相比,创建对象还需要额外的开销,例如分配以及释放堆内存等。如果只需要保存int/float/double/char等非对象类型,那么通常使用CGRect这个种结构体就可以了。

要点

  • Objective-C为C语言添加了面向对象的特性,是其超集。Objective-C使用动态绑定的消息结构,也就是说,在运行时才会检查对象类型。接收一条消息之后,究竟应执行何种代码,由运行期而非编译器决定。
  • 理解C语言的核心概念有助于写好Objective-C程序。尤其要掌握内存模型与指针。

第一条:了解Objective-C语言的起源的更多相关文章

  1. Effective Objective-C 2.0 — 第一条:了解Objective-C语言的起源

    第一条: 了解Objective-C语言的起源 由Smalltalk演化而来,消息型语言的鼻祖(messaging structure)而非 (function calling)函数调用 //Mess ...

  2. 第1条:了解Objective-C 语言的起源

    1.OC语言是由Smalltalk演化而来.该语言使用“消息结构” 而 非“函数调用”. 使用“消息结构”的语言,其运行时所执行的代码由运行环境来决定: 编译器不需要关心接收消息的对象是什么类型,只在 ...

  3. 第一章 熟悉Objective -C 编写高质量iOS与OS X代码的52 个有效方法

    第一章 熟悉Objective -C   编写高质量iOS与OS  X代码的52 个有效方法   第一条: 了解Objective-C 语言的起源 关键区别在于 :使用消息结构的语言,其运行时所应执行 ...

  4. 1.2《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——开始第一条命令

    现在开始准备运行我们的第一条命令了,在屏幕上打印'hello'.(字符打印的地方被称为'标准输出',通常指的是屏幕,很少指真的物理打印机设备).这条命令就是echo,这条命令的参数是想要输出的字符串或 ...

  5. 【网络爬虫入门01】应用Requests和BeautifulSoup联手打造的第一条网络爬虫

    [网络爬虫入门01]应用Requests和BeautifulSoup联手打造的第一条网络爬虫 广东职业技术学院 欧浩源 2017-10-14  1.引言 在数据量爆发式增长的大数据时代,网络与用户的沟 ...

  6. 教你用Elastic Search:运行第一条Hello World搜索命令

    摘要:Elastic Search可实时对数据库进行全文检索.处理同义词.从同样的数据中生成分析和聚合数据. 本文分享自华为云社区<Elastic Search入门(一): 简介,安装,运行第一 ...

  7. Oracle 查询出来的数据取第一条

    Oracle 查询出来的数据取第一条 --------------------------------------------------------------------------- 转载自:h ...

  8. oracle分组后取每组第一条数据

    数据格式: 分组取第一条的效果: sql语句: SELECT * FROM ( ;

  9. MSSQL 分组后取每组第一条(group by order by)

    查询中经常遇到这种查询,分组后取每组第一条.分享下一个SQL语句: --根据 x 分组后.根据 y 排序后取第一条 select * from ( select ROW_NUMBER() over(p ...

随机推荐

  1. 【随笔】nginx add_header指令的使用

    nginx配置文件通过使用add_header指令来设置response header. 具体方法如下: add_header key value add_header Cache-Control n ...

  2. Kafka实战-Kafka到Storm

    1.概述 在<Kafka实战-Flume到Kafka>一文中给大家分享了Kafka的数据源生产,今天为大家介绍如何去实时消费Kafka中的数据.这里使用实时计算的模型——Storm.下面是 ...

  3. cgroup其他部分 IO + hugepage

    cgroup还有其他一些限制特性,如io,pid,hugetlb等,这些用处不多,参见Cgroupv1.下面介绍下与系统性能相关的io和hugepage,cgroup的io介绍参考Cgroup - L ...

  4. SQL 必知必会·笔记<11>创建高级联结

    1. 使用表别名 SQL 除了可以对列名和计算字段使用别名,还允许给表名起别名.这样 做有两个主要理由: 缩短SQL 语句: 允许在一条SELECT 语句中多次使用相同的表. 使用表别名示例: SEL ...

  5. SQL 必知必会·笔记<5>创建计算字段

    字段(field) 基本上与列(column)的意思相同,经常互换使用,不过数据库列一 般称为列,而术语字段通常与计算字段一起使用. 拼接(concatenate) 将值联结到一起(将一个值附加到另一 ...

  6. Linux常用命令-vim

    vim的基本模式 1普通模式Normal mode 输入vim命令后进入的就是普通模式. 2插入模式Insert mode 这是内容修改编辑的模式, 在普通模式进入插入模式方法 按i或insert 在 ...

  7. 梯度下降法原理与python实现

    梯度下降法(Gradient descent)是一个一阶最优化算法,通常也称为最速下降法. 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离 ...

  8. JavaWeb学习 (二十一)————基于Servlet+JSP+JavaBean开发模式的用户登录注册

    一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp ...

  9. JavaWeb学习(二)———Tomcat服务器学习和使用(一)

    一.Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件. 如果想修改Tomcat服务器的启动端口,则可以在server.xml ...

  10. 源码编译安装MySQL8.0

    源码编译安装MySQL8.0 0.前期准备条件 查看linux的版本 [root@mysql etc]# cat /etc/redhat-release CentOS Linux release 7. ...