【zz】C++开发者快速学习Objective-C语言核心语法

Objective-C 入门篇 前言 Objective-C(下面简称OC)是由C语言扩展出来的,其火星文写法对于之前从事Java开发的同学颇感蛋疼。本文侧重介绍常用的语法,通过对比Java并结合本人入门的过程和经验,帮助有需求的同学快速掌握OC基本编程,为IOS的入门奠定语言基础。首先是写第一行代码,恭喜正式进入OC学习阶段。 int main(int argc, char *argv[]) { @autoreleas... 阅读详情

原文地址:http://mobile.51cto.com/hot-234791.htm

补充阅读:http://mobile.51cto.com/hot-232833.htm

类并不是特殊的

在Smalltalk中,类是具有一些特性的对象。在Objective-C中也一样。一个类是一个对象,对象回应消息。Objective-C和C++都分离了对象分配和初始化。

在C++中,对象分配通过新的操作。在Objective-C中,这样的操作是通过给类发送分配消息—调用malloc()或者一个等价。

C++中的初始化是通过调用一个与类同名的函数。Objective-C并没有区别初始化方法和其他方法,但出于惯例缺省的初始化方法就是初始化。

当你声明一个方法让实例去回应,声明通常已“-”开头,并且“+”用作类的方法。在文档中对这些消息使用一些前缀是很普遍的,所以你也可以说+alloc和-init来暗示alloc是传给一个类,init传给实例。

类在Objective-C中,正如在其他一些面向对象语言,都是对象工厂。大多数类不用自行实现+alloc,而是从他们的父类中继承。在NSObject中,父类在大多数Objective-C程序中,+alloc方法调用+allocWithZone:.使NSZone作为一个参数,一个C结构包含对象分配的一些策略。回顾19世纪80年代,当Objective-C用在NeXTstep来实现设备驱动和只有8MB内存25MHZ的CPU机器的GUI上面时,NSZone对优化非常重要。同时,这或多或少的被Objective-C程序员所忽视。(很有可能成为象NUMA构架一样流行,更普遍。)

众多优秀的特性之一就是对象创建语义是由库定义的并且语言不是类簇的思想。当你传一个-init消息给对象时,它返回一个初始化对象。这可能是你发送消息的那个对象,但不一定肯定就是。这和其他初始化程序一致的。很有可能一些公共类的特殊子类在不同数据上更有效。

实现这个特性的通用方法叫做isa-swizzling。正如我前述,Objective-C对象是C结构,这些结构第一个元素是指向类的指针。这个元素是可存取的,正如其他实例变量一样;你可以在运行时通过分配新值来改变对象的类。当然,如果你对对象的类设置在内存中有着不同的布局,这些设置可能严重错误。

然而,你可以通过一个父类来定义布局和通过子集的集合定义行为,举例来说,这个技术用在标准化字符串类(NSString),它对不同的文本字符集、静态事物和其它一些有着各种各样的实例。

因为类是对象,你可以象操作对象一样操作他们。举例来说,你可以把他们放在集合。当我有一些输入事件需要通过不同的类的实例来处理时我就使用这种格式。你需要创建一个目录映射事件命名到类,然后为每一个输入事件实例化一个对象。如果你在一个库中这么做,它允许代码的使用者轻松的注册属于他们自己的句柄。

类型和指针

Objective-C没有公开允许在堆栈上定义对象。但并不是真的—很有可能在堆栈上定义对象,但有些困难,因为它破坏了对内存管理的一种假设。结果,每一个Objective-C对象都是一个指针。一些类型由Objective-C定义;这些类型在头部定义作为C类型。

在Objective-C中最普遍的3种类型就是id,Class和SEL。id就是指向Objective-C对象的指针,它等价于C语言中的void*,你可以映射任何对象指针类型指向它并且映射他指向其它的对象指针类型。

你可以传任何消息给id,但如果不支持的话会返回一个运行时异常。

类是指向Objective-C类的指针。类是对象,所以也可以接收消息。类名是一种类型,不是可变的。标识符NSObject是一个NSObject实例的类型,但也可作为消息接受者。你可以获得一个类,如下:

   
  1. [NSObject class];  
  2.  

发送一个+class消息给NSObject类,然后返回一个指向代表类的类结构指针。

这对我们回顾是非常有用的[FS:PAGE],正如我们在这个系列第二部分看到的一样。

第三种类型SEL,代表一个选择器—一个代表方法名的抽象。你可以在编译时通过@selector()直接创建,或在运行时通过C字符串调用运行时库函数,或用OpenStep NSSelectorFromString()函数,这个函数给Objective-C字符串一个选择器。这个技术允许你通过名字调用方法。你可以在C中通过使用类似dlsym(),但在C++中非常不同。在Objective-C中,你可以做的如下:

   
  1. [object perfomSelector:@selector(doSomething)];  
  2.  

这等价于如下:

   
  1. [object doSomething];  
  2.  

显然,第二种格式速度稍微快些,因为第一种传送两个消息。后面,我们会看到通过选择器处理的一些细节。

C++没有与id相同的类型。因为对象总是可以类型化的。在Objective-C,你可以选择类型系统。下面的两种都是有效的:

   
  1. id object = @”a string”;  
  2.  
  3. NSString *string = @”a string”;  
  4.  

常量字符串实际上是NSConstantString类的一个实例,NSConstantString类是NSString的子类。将它引用到NSString* 使编译时对消息进行类型检查和存储公共实例变量(这在Objective-C从未使用过)。注意你可以通过如下改变这一设置:

   
  1. NSArray *array = (NSArray*)string;  
  2.  

如果给数组发送消息,编译器将会检查NSArray能接收的消息。这并不是非常有用,因为对象是一个字符串。如果发送一个NSArray和NSString实现的消息,可能会有作用。如果你发送的消息NSString没有实现,一个异常将会抛出。

强调Objective-C和C++的不同的这件事看起来比较奇怪。Objective-C有类型-值语法,而C++有类型-变量语法。在Objective-C,对象类型是对象专有的一种属性。在C++,类型取决于变量的类型。

在C++中,当你指派一个指针指向一个对象到一个变量定义一个指向父类的指针,两个指针可能没有相同的数值(这可以通过多继承实现,而Objective-C不支持这种。)

定义类

Objective-C类定义有一个接口和一个实现部分。与C++有相似的地方,但两个稍微有些混。

Objective-C中的接口仅定义位并且明确的需要公开。对于实现的原因,这包括私有实例变量在大部分的实现中,因为你无法继承一个类除非你知道它多大。最近的一些实现,象Apple的64位运行时则没有这种限制。

Objective-C对象的接口如下:

   
  1. @interface AnObject : NSObject  
  2.  
  3. {  
  4.  
  5. @private  
  6.  
  7. int integerivar  
  8.  
  9. @public  
  10.  
  11. id anotherObject;  
  12.  
  13. }  
  14.  
  15. + (id) aClassMethod;  
  16.  
  17. - (id) anInstanceMethod:(NSString*)aString with:(id)anObject  
  18.  
  19. @end  
  20.  

第一行包含3个部分。标识符AnObject 是新类的名字。冒号后面的名字是NSObject。(这是可选的,但每一个Objective-C 对象都应拓展NSObject)。在括号内的名字是协议——与Java中的接口相似——通过类来实现。

正如C++实例变量(C++中的域)可以存取修饰符,不象C++,这些修饰符以@为前缀是为了避免与C标识符冲突。

Objective-C不支持多继承,所以只有一个父类。所以,对象第一部分的布局总是与父类实例的布局一致。这在过去常常定义为动态,意味着改变类中实例变量需要它所有子类重新编译。在较新的运行时这种限定并不要求,在存取实例实例变量上开支稍微大些。这种决策的另一个影响就是Objective-C其他特性中的一个。

   
  1. struct_AnObject  
  2.  
  3. {  
  4.  
  5. @defs(AnObject);  
  6.  
  7. };  
  8.  

@def表示着对特定对象所有域都插入这种结构,所以struct_AnObject 和AnObject类的实例有着相同的内存结构。举个例子来说,你可以通过这种规则可以直接存取实例变量。一个通常的用法就是允许C函数直接操作Objective-C对象,是基于性能原因。
正如我前面暗示的,与这个特性相关的另一件事就是可以在堆栈上创建对象。因为结构和对象在[FS:PAGE]内存布局中有着相同的结构,你可以简单的创建结构,设置他的指针指向正确的类,然后映射一个指针指向一个对象指针。然后你可以当做对象来使用,虽然你不得不小心没有什么可以保持指针不越界。(现实世界中我从没有使用这种方法,仅仅理论上可能。)

不象C++,Objective-C没有私有的或受保护的方法。Objective-C对象上的任何方法可以被其他对象调用。如果你在接口中没有声明方法,就是非正式私有的。将会得到运行时警告:对象不回应这种消息,但是你任然可以调用它。

接口和C中头部声明很相似。但它仍然需要一个实现,这并不奇怪,可以使用@implementation来定义。

 

   
  1. @implementation AnObject  
  2.  
  3. + (id) aClassMethod  
  4.  
  5. {  
  6.  
  7. ...  
  8.  
  9. }  
  10.  
  11. - (id) anInstanceMethod:(NSString*)aString with:(id)anObject  
  12.  
  13. {  
  14.  
  15. ...  
  16.  
  17. }  
  18.  
  19. @end  
  20.  

注意参数类型是特定的,在括号里。这是从C重用映射语法来展示值映射到类型;他们可能不是类型。准确来说当映射时应用相同的规则。这意味着映射在不兼容对象指针类型间会导致一个警告(不是错误)。

内存管理

传统的,Objective-C不提供任何内存管理。在早期版本中,对象类实现一个+new方法调用malloc()来创建一个新对象。当使用完这个对象,传一个-free消息。任何一个对象从NSObject继承回应一个-retain和-release消息。当你使用完这个对象,你传一个-free消息。OpenStep添加了参考计算。

每一个从NSObject继承的对象都回应-retain和-release消息。当你想要保留一个指向对象的指针,你可以发送一个-retain消息。当你使用完以后,你可以发送一个-release消息。

这个设计有个细微问题。通常你不需要保持一个指向对象的指针,但是你也不想释放。一个典型的例子在返回一个对象时候,调用者需要保持指向对象的指针,但你不想这么做。

这个问题的解决方案就是NSAutoreleasePool类。加上-retain和-release,NSObject也回应-autorelease消息。当你发送其中一个,和现前的自动释放池一同注册。当这个池对象被注销,它发送一个-release消息给每个对象,而对象在这之前先收到-autorelease消息。在OpenStep应用中,一个NSAutoreleasePool实例在循环开始的时候创建,在结束的时候销毁。你也可以创建属于你自己的实例来自动释放对象。

这个机制减少了一些C++所需的复制。其实也不值得这么做,在Objective-C,易变性是对象的属性,不是参考。在C++,有常量指针和非常量指针。不允许在常量对象上调用非常量方法。这保证不了对象不会被改变——仅仅因为你不想改变。

在Objective-C中,一个常态模式定义了一个不变的类和可变的子类。NSString就是一个典型例子;

它有一个可变的子类NSMutableString。如果你得到NSString并且想保存下来,你可以传一个-retain消息并且不用复制操作就可以保存指针。相反地,你可以传一个+stringWithString:message给NSString。不管这个参数是否可变都会检查并返回原始指针。

在Apple和GNU运行时,Objective-C都支持存储性的垃圾回收,这会避免对-retain和-release的需要。在现存的框架中对语言的附加并不总是很好的支持的,并且在用的时候需要格外小心。

总结

既然我们已经浏览了Objective-C语言的核心,在这部分的总结我们将会看到更多的一些高级话题。

逆向分析踩坑记:当Frida在x86模拟器上‘看不见’ARM的so文件时,我们该如何手动定位与验证? 本文探讨了在x86模拟器上使用Frida进行逆向分析时,无法检测到ARM架构so文件的解决方案。通过分析内存映射、Frida的视觉盲区及手动定位技术,提供了兼容层、混合调试和原生ARM环境三种实用方案,帮助逆向工程师突破工具限制,实现精准定位与验证。 阅读详情

相关推荐

PyTorch实战(4)——卷积神经网络(Convolutional Neural Network,CNN)

卷积神经网络 (Convolutional Neural Network, CNN) 是一种广泛应用的深度学习模型。通过参数共享、局部感知和空间结构等优势,能够更好地处理图像数据,并在图像识别、目标检测和图像生成等任务中展现出强大的能力。在本节中,介绍了卷积的计算方法以及卷积神经网络的基本组件,并使用 PyTorch 构建了卷积神经网络以深入了解其工作原理。

盼小辉丶的博客 1万+

十分钟让你明白Objective-C的语法(和Java、C++的对比)

很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼,Objective-C的代码在语法上和Java, C++有着很大的区别,有的同学会感觉像是看天书一样。不过,语言都是相通的,有很多共性。下面列出Objective-C语言语法和Java,C++的对比,这样你就会很容易Objective-C的语法是怎么回事了。 先目睹一下

刚刚在线 993

iOS与macOS混合编程实战:Objective-C、C、C++的高效整合

C库在Objective-C中的封装主要涉及到创建一个适配层,这个适配层能够将C库的原生调用接口转换为Objective-C风格的接口。Objective-C拥有面向对象的特性,支持引用计数的内存管理,因此需要特别注意封装时的内存管理问题。实现封装的基本思路有以下几种:使用Objective-C函数指针模拟C接口创建C结构体的Objective-C类封装使用Objective-C函数包装C函数调用。

weixin_35755823的博客 850

iOS,java语法对比

很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼,Objective-C的代码在语法上和Java, C++有着很大的区别,有的同学会感觉像是看天书一样。不过,语言都是相通的,有很多共性。下面列出Objective-C语言语法和Java,C++的对比,这样你就会很容易Objective-C的语法是怎么回事了。 先

No Excuses! Confidence! Vigorous! 1637

Objective-C和C++语法比较

1)实例方法和对象方法 C++语言中,对象方法的写法可能是: void hello(bool ishello) { ...... } C++语言中,类的方法的写法可能是: static void hello(bool ishello) { ...... } 用Objective-C写出来的对象方法就是 -(void) hello:(BOOL)ishello { ...... } 用Objective-C写出来的类方法就是 +(void) hello:(BOOL)ishello { ......

thehunters的专栏 2027

【OC】c++快速上手oc语法

c++语言快速上手OC语言

cheng_lin0201的博客 610

Objective-C】从C++转向Objective-C的全面指南

Objective-C初学者请进(尤其是从C++转过来的)

qq_33868975的博客 1133

C++开发者快速学习Objective-C语言核心语法

本文将Objective-C讨论了语言核心语法。这部分开始详述一些具体的语法。正如你期待的一样,涉及到了定义和类。 51CTO推荐专题:iPhone应用程序开发初探 类并不是特殊的 在Smalltalk中,类是具有一些特性的对象。在Objective-C中也一样。一个类是一个对象,对象回应消息。Objective-C和C++都分离了对象分配和初始化。 在C++中,对象

风---的专栏 775

Objective-C与C语言关系解析:从语法到苹果开发生态

C语言作为编译型语言的代表,其语法结构和指针操作奠定了现代编程语言的基础。通过引入Smalltalk的消息传递机制,Objective-C在C语言之上构建了动态的面向对象模型,实现了运行时多态和动态绑定。这种设计使得Objective-C能够与C++代码混合编译,形成Objective-C++模式,为高性能计算和复用现有C++库提供了技术路径。在苹果开发生态中,这一技术价值体现在Cocoa框架的构建和Xcode工具链的深度整合上,使得开发者能够高效构建macOS和iOS应用。本文围绕C系语言谱系、Objec

343

Import多语言支持:Swift、Objective-C、C++、C的import语法全解析

Import是一款强大的Xcode扩展工具,能够帮助开发者从代码中的任何位置快速添加导入语句,显著提升iOS/macOS开发效率。无论是Swift、Objective-C这种Apple生态主流语言,还是C++、C等系统级开发语言,Import都能提供精准的导入支持,让开发者告别手动编写import语句的繁琐工作。 [![Import扩展工具图标](https://raw.gitcode.com/

gitblog_01027的博客 920

Objective-C语言的区块链

Objective-C是一种面向对象的编程语言,最早由Brad Cox和Tom Love在1980年开发。它结合了小型程序设计语言Smalltalk)的消息传递特性与C语言的效率,成为苹果公司开发iOS和macOS应用的重要语言之一。面向对象:支持类和继承,能够方便地进行面向对象编程。动态性:在运行时可以动态创建和使用对象,支持动态类型和消息传递。C语言兼容:由于其基于C语言,能够直接调用C库,适用于需要高性能的应用。

2501_90425958的博客 2380

Objective-C语言学习路线

Objective-C于1970年代由Brad Cox和Tom treasures开发,是一种在C语言基础上增加了面向对象特性的语言。它最初被设计用来开发复杂的软件系统,特别是在NeXT公司(随后被苹果收购)中得到了广泛应用。随着iOS和macOS的兴起,Objective-C成为了苹果开发的主要语言之一。学习Objective-C是一个逐步积累的过程,从基础语言知识,到框架使用,再到项目实践和进阶技巧,都需要投入时间和精力。

2501_90494615的博客 336

安全人员的Objective-C学习笔记

注: 本文首发于我的个人博客:https://evilpan.com/2019/04/05/objc-basics/ 如果你有其他语言学习经验,要学习Objective-C的语法特性其实并不困难。正如我之前在软件开发的一些"心法"一文中所说,编程语言只是一个工具,工具本身不是目的,关键是要看你用来做什么。 而我学习Objective-C的理由也很简单,就是为了逆向破解iOS和mac...

有价值炮灰 397

Objective-C 基础教程——入门

来自 http://www.runoob.com/w3cnote/objective-c-tutorial.html Objective-C 是一种简单的计算机语言,设计为可以支持真正的面向对象编程。 Objective-C 通过提供类定义,方法以及属性的语法,还有其他可以提高类的动态扩展能力的结构等,扩展了标准的 ANSI C 语言。类的语法和设计主要是基于 Smalltalk,最早的面向对...

Zhanganliu的博客 1677

Objective-C、C与C++的区别

【代码】Objective-C、C与C++的区别。

qq_42757463的博客 1326

OC语法学习小结

1、定义类: @interface 类名 : 父类 @end 2、使用:(冒号)表示继承一个类 Student : NSObject 3、使用()定义一个Catagory(类别) * 作用:在不改变原有类结构的基础上,扩展原有类的方法(不能扩展属性),但不建议重载原有类的方法 * 开发工具默认生成的文件为:类名+Catagory名称 * Catagory可以写在

技术改变生活 2606

Objective-C的语法简要说明(c++对照)

很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼,Objective-C的代码在语法上和Java, C++有着很大的区别,有的同学会感觉像是看天书一样。不过,语言都是相通的,有很多共性。下面列出Objective-C语言语法和Java,C++的对比,这样你就会很容易Objective-C的语法是怎么回事了。 先目睹

epeaktop的专栏 914

Mybatis源码学习(四)自定义Mapper方法执行流程

Mybatis源码学习(一)初探执行流程前言1. 寻觅官网demo, quick start2. 根据demo画出调用流程图3. Learn With Questions文章链接 前言 作为业界使用最广的ORM层框架,没有之一.想要翻身码农把歌唱,怎么能不去学习他的源码呢!!! Let’s do it! 注: Mybatis版本3.5.5, 数据库为Mysql 所有后续的mybatis源码学习都是基于上述版本 1. 寻觅官网demo, quick start 窃以为熟悉一个框架的最好方式就是官网下载demo

K_Tang的博客 1856

基于Python的硬币识别系统设计与实现.zip

基于Python的硬币识别系统设计与实现

上一篇: 很多都完全讲中我的心理弱点 需要常常反复看
odola
博客等级 码龄19年 8粉丝 11原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值