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

news/2024/7/20 12:52:26 标签: 移动开发, c/c++, 内存管理

第一条:了解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实例的内存地址。
Valid XHTML
此图片内存布局演示了一个 分配在堆中的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程序。尤其要掌握内存模型与指针。

http://www.niftyadmin.cn/n/1679174.html

相关文章

linux编译驱动模块必要条件,linux驱动模块的Makefile分析

1&#xff0e;获取内核版本当设备驱动需要同时支持不同版本内核时&#xff0c;在编译阶段&#xff0c;内核模块需要知道当前使用的内核源码的版本&#xff0c;从而使用相应的内核 API。2.4 与 2.6 内核下&#xff0c;源码头文件 linux/version.h 定义有&#xff1a;LINUX_VERSI…

在.net中怎么对比相同结构xml的值,并生成差异节点列表?

例如&#xff1a; a: <Cargo> <ID>1</ID> <Size>20</Size> <Color /> </Cargo> b: <Cargo> <ID>1</ID> <Size>200</Size> <Color>30<Color> </Cargo> 希望生成的错误列表&#xff…

可以将class文件反编译成java文件

假设将jad.exe安装在f:\java\jad目录下把要反编译的文件*.class复制到此目录下&#xff0c;接着接以下步骤&#xff0c;在命令行窗口环境中进入jad目录&#xff0c;然后运行&#xff1a;jad -s java *.class (附&#xff0c;*.class指要反编译的文件名)如果*.class文件和jad程序…

linux下caffe如何写代码,Linux使用技巧之阅读代码时如何快速追踪某个关键字.txt...

使用Linux grep命令:$ grep -n -H -R "REGISTER_LAYER_CREATOR"src/caffe/layer_factory.cpp:74:REGISTER_LAYER_CREATOR(Convolution, GetConvolutionLayer);src/caffe/layer_factory.cpp:112:REGISTER_LAYER_CREATOR(Pooling, GetPoolingLayer);src/caffe/layer_fa…

Mac配置maven环境变量

1.配置maven环境变量前必须先配置好Java环境变量 2.打开终端输入vim ~/.bash_profile编辑配置文件 3.英文输入法下按i进入编辑模式 4.把下面两行配置写进去&#xff0c;注意第一行要换成你的目录 export Maven_HOME/Users/mac/kaifaruanjian/apache-maven-3.8.4 export PATH$P…

nodeJs 使用npm把模块设置成全局命令后报错

为什么80%的码农都做不了架构师&#xff1f;>>> 我的文件里是这样写的 var fs require(fs); fs.mkdirSync(aaa);它报了个这样的错误 fanmingfeideMBP:testN fanmingfei$ npm link /usr/local/bin/testn -> /usr/local/lib/node_modules/testn/cli.js /usr/loca…

ArcGIS的GeoProcessing的原理及实现(1)

ArcGIS将GIS看作3种视图&#xff1a;地图、数据集、空间处理模型&#xff0c;分别对应于其产品的ArcMap、GeoDatabase、GeoProcessing。其中&#xff0c;对于研究者&#xff0c;GeoProcessing更具有实用价值和意义&#xff0c;因为对于研究者&#xff0c;面对问题&#xff0c;构…

解决 不可识别的数据库格式 'J:\ceshi_paixu\class.accdb'。

今天练习网站&#xff0c;换数据库了&#xff0c;不用sql server 2005了&#xff0c;因为在我的机子上.用sql server 2005太慢了&#xff0c;不知道怎么回事&#xff0c;因此又用access数据库&#xff0c;因为我的机子上装的是2007的&#xff0c;但以前一直没用过建2007格式的&…