Objective-C 快速指南


Objective-C 概述

Objective-C 是在 C 编程语言之上开发的通用语言,添加了 Small Talk 编程语言的功能,使其成为一种面向对象的语言。它主要用于开发 iOS 和 Mac OS X 操作系统及其应用程序。

最初,Objective-C 是由 NeXT 为其 NeXTSTEP 操作系统开发的,后来被 Apple 接管用于其 iOS 和 Mac OS X。

面向对象编程

完全支持面向对象编程,包括面向对象开发的四大支柱 -

  • 封装
  • 数据隐藏
  • 遗产
  • 多态性

示例代码

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   NSLog (@"hello world");
   [pool drain];
   return 0;
}

基础框架

Foundation Framework 提供了大量功能,如下所列。

  • 它包括一系列扩展数据类型,如 NSArray、NSDictionary、NSSet 等。

  • 它由一组丰富的操作文件、字符串等的函数组成。

  • 它提供了 URL 处理、日期格式化、数据处理、错误处理等实用程序的功能。

学习 Objective-C

学习 Objective-C 时最重要的事情是关注概念,不要迷失在语言技术细节中。

学习编程语言的目的是成为一名更好的程序员;也就是说,在设计和实施新系统以及维护旧系统方面变得更加有效。

Objective-C 的使用

正如前面提到的,Objective-C 用于 iOS 和 Mac OS X。它拥有庞大的 iOS 用户基数,并且 Mac OS X 用户也在大幅增长。由于 Apple 注重质量第一,因此对于那些开始学习 Objective-C 的人来说这真是太棒了。

Objective-C 环境设置

本地环境设置

如果您仍然愿意为 Objective-C 编程语言设置环境,您的计算机上需要有以下两个软件:(a) 文本编辑器和 (b) GCC 编译器。

文本编辑器

这将用于输入您的程序。少数编辑器的示例包括 Windows 记事本、操作系统编辑命令、Brief、Epsilon、EMACS 和 vim 或 vi。

文本编辑器的名称和版本可能因不同操作系统而异。例如,记事本将在 Windows 上使用,vim 或 vi 可以在 Windows 上使用,也可以在 Linux 或 UNIX 上使用。

您使用编辑器创建的文件称为源文件,包含程序源代码。Objective-C 程序的源文件通常以扩展名“ .m ”命名。

在开始编程之前,请确保您有一个文本编辑器,并且您有足够的经验来编写计算机程序、将其保存在文件中、编译并最终执行它。

GCC 编译器

源文件中编写的源代码是程序的人类可读源。它需要被“编译”成机器语言,这样你的CPU才能真正按照给定的指令执行程序。

该 GCC 编译器将用于将您的源代码编译为最终的可执行程序。我假设您具有有关编程语言编译器的基本知识。

GCC 编译器可以在各种平台上免费使用,下面解释了在各种平台上设置的过程。

在 UNIX/Linux 上安装

第一步是安装 gcc 和 gcc Objective-C 包。这是通过 -

$ su - 
$ yum install gcc
$ yum install gcc-objc

下一步是使用以下命令设置包依赖项 -

$ yum install make libpng libpng-devel libtiff libtiff-devel libobjc 
   libxml2 libxml2-devel libX11-devel libXt-devel libjpeg libjpeg-devel

为了获得 Objective-C 的完整功能,请下载并安装 GNUStep。这可以通过从http://main.gnustep.org/resources/downloads.php下载包来完成。

现在,我们需要切换到下载的文件夹并通过以下方式解压文件:

$ tar xvfz gnustep-startup-.tar.gz

现在,我们需要切换到使用以下命令创建的文件夹 gnustep-startup -

$ cd gnustep-startup-<version>

接下来,我们需要配置构建过程 -

$ ./configure

然后,我们可以通过以下方式构建 -

$ make

我们最终需要通过以下方式设置环境 -

$ . /usr/GNUstep/System/Library/Makefiles/GNUstep.sh

我们有一个 helloWorld.m Objective-C,如下 -

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
   NSLog (@"hello world");
   [pool drain];
   return 0;
}

现在,我们可以编译并运行一个 Objective-C 文件(例如 helloWorld.m),方法是使用 cd 切换到包含该文件的文件夹,然后使用以下步骤 -

$ gcc `gnustep-config --objc-flags` 
-L/usr/GNUstep/Local/Library/Libraries 
-lgnustep-base helloWorld.m -o helloWorld
$ ./helloWorld

我们可以看到以下输出 -

2013-09-07 10:48:39.772 tutorialsPoint[12906] hello world

Mac 操作系统上的安装

如果您使用 Mac OS X,获取 GCC 的最简单方法是从 Apple 网站下载 Xcode 开发环境并按照简单的安装说明进行操作。设置 Xcode 后,您将能够使用 C/C++ 的 GNU 编译器。

Xcode 目前可在developer.apple.com/technologies/tools/上获取。

在 Windows 上安装

为了在Windows上运行Objective-C程序,我们需要安装MinGW和GNUStep Core。两者均可从https://www.gnu.org/software/gnustep/windows/installer.html获取。

首先,我们需要安装MSYS/MinGW系统包。然后,我们需要安装 GNUstep Core 软件包。两者都提供了 Windows 安装程序,这是不言自明的。

然后通过选择“开始”->“所有程序”->“GNUstep”->“Shell”来使用 Objective-C 和 GNUstep

切换到包含 helloWorld.m 的文件夹

我们可以使用 -

$ gcc `gnustep-config --objc-flags` 
-L /GNUstep/System/Library/Libraries hello.m -o hello -lgnustep-base -lobjc

我们可以使用 -

./hello.exe

我们得到以下输出 -

2013-09-07 10:48:39.772 tutorialsPoint[1200] hello world

Objective-C 程序结构

在我们学习 Objective-C 编程语言的基本构建块之前,让我们看一下最基本的 Objective-C 程序结构,以便我们可以将其作为后续章节的参考。

Objective-C Hello World 示例

Objective-C 程序基本上由以下部分组成 -

  • 预处理器命令
  • 界面
  • 执行
  • 方法
  • 变量
  • 陈述和表达式
  • 评论

让我们看一个简单的代码,它将打印“Hello World”一词 -

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
- (void)sampleMethod;
@end

@implementation SampleClass

- (void)sampleMethod {
   NSLog(@"Hello, World! \n");
}

@end

int main() {
   /* my first program in Objective-C */
   SampleClass *sampleClass = [[SampleClass alloc]init];
   [sampleClass sampleMethod];
   return 0;
}

让我们看看上面程序的各个部分 -

  • 程序的第一行#import <Foundation/Foundation.h>是一个预处理器命令,它告诉 Objective-C 编译器在实际编译之前包含 Foundation.h 文件。

  • 下一行@interface SampleClass:NSObject显示如何创建接口。它继承了NSObject,它是所有对象的基类。

  • 下一行- (void)sampleMethod; 展示如何声明方法。

  • 下一行@end标记接口的结束。

  • 下一行@implementation SampleClass显示了如何实现接口 SampleClass。

  • 下一行- (void)sampleMethod{}显示了sampleMethod 的实现。

  • 下一行@end标记实现的结束。

  • 下一行int main()是程序开始执行的主函数。

  • 下一行 /*...*/ 将被编译器忽略,它已被添加到程序中添加附加注释。所以这样的行在程序中称为注释。

  • 下一行NSLog(...)是 Objective-C 中可用的另一个函数,它会导致消息“Hello, World!” 要显示在屏幕上。

  • 下一行返回0;终止 main() 函数并返回值 0。

编译并执行 Objective-C 程序

现在,当我们编译并运行该程序时,我们将得到以下结果。

2017-10-06 07:48:32.020 demo[65832] Hello, World!

Objective-C 基本语法

您已经了解了 Objective-C 程序的基本结构,因此很容易理解 Objective-C 编程语言的其他基本构建块。

Objective-C 中的令牌

Objective-C 程序由各种标记组成,标记可以是关键字、标识符、常量、字符串文字或符号。例如,以下 Objective-C 语句由六个标记组成 -

NSLog(@"Hello, World! \n");

各个令牌是 -

NSLog
@
(
   "Hello, World! \n"
)
;

分号;

在 Objective-C 程序中,分号是语句终止符。也就是说,每个单独的语句必须以分号结束。它表示一个逻辑实体的结束。

例如,以下是两个不同的语句 -

NSLog(@"Hello, World! \n");
return 0;

评论

注释就像 Objective-C 程序中的帮助文本一样,它们会被编译器忽略。它们以 /* 开头并以字符 */ 结尾,如下所示 -

/* my first program in Objective-C */

您不能在注释中添加注释,并且它们不会出现在字符串或字符文本中。

身份标识

Objective-C 标识符是用于标识变量、函数或任何其他用户定义项的名称。标识符以字母 A 到 Z 或 a 到 z 或下划线 _ 开头,后跟零个或多个字母、下划线和数字(0 到 9)。

Objective-C 不允许在标识符中使用标点符号,例如 @、$ 和 %。Objective-C 是一种区分大小写的编程语言。因此,Manpowermanpower在 Objective-C 中是两个不同的标识符。以下是可接受的标识符的一些示例 -

mohd       zara    abc   move_name  a_123
myname50   _temp   j     a23b9      retVal

关键词

下面的列表显示了 Objective-C 中的一些保留字。这些保留字不得用作常量、变量或任何其他标识符名称。

汽车 别的 长的 转变
休息 枚举 登记 类型定义
案件 外部的 返回 联盟
字符 漂浮 短的 未签名
常量 为了 空白
继续 大小 易挥发的
默认 如果 静止的 尽管
整数 结构体 _包装好的
双倍的 协议 界面 执行
NS对象 NS整数 NS编号 CG浮动
财产 非Atomics的; 保持 强的
虚弱的 不安全_未保留; 读写 只读

Objective-C 中的空白

仅包含空格(可能带有注释)的行称为空行,Objective-C 编译器完全忽略它。

空白是 Objective-C 中用来描述空白、制表符、换行符和注释的术语。空格将语句的一部分与另一部分分隔开,并使编译器能够识别语句中一个元素(例如 int)的结束位置和下一个元素的开始位置。因此,在以下声明中 -

int age;

int 和age 之间必须至少有一个空白字符(通常是空格),以便编译器能够区分它们。另一方面,在下面的声明中,

fruit = apples + oranges;   // get the total fruit

水果和 = 之间或 = 和苹果之间不需要空格字符,但如果您希望出于可读性目的,可以自由地包含一些空格字符。

Objective-C 数据类型

在 Objective-C 编程语言中,数据类型是指用于声明不同类型的变量或函数的广泛系统。变量的类型决定了它在存储中占用多少空间以及如何解释存储的位模式。

Objective-C 中的类型可以分类如下:

先生。 类型和描述
1

基本类型 -

它们是算术类型,由两种类型组成:(a) 整数类型和 (b) 浮点类型。

2

枚举类型 -

它们又是算术类型,用于定义在整个程序中只能分配某些离散整数值的变量。

3

类型 void -

类型说明符void表示没有可用值。

4

派生类型 -

它们包括 (a) 指针类型、(b) 数组类型、(c) 结构类型、(d) 联合类型和 (e) 函数类型。

数组类型和结构类型统称为聚合类型。函数的类型指定函数的返回值的类型。我们将在下一节中看到基本类型,而其他类型将在接下来的章节中介绍。

整数类型

下表为您提供了有关标准整数类型及其存储大小和值范围的详细信息 -

类型 存储大小 取值范围
字符 1字节 -128 至 127 或 0 至 255
无符号字符 1字节 0 至 255
签名字符 1字节 -128 至 127
整数 2 或 4 字节 -32,768 至 32,767 或 -2,147,483,648 至 2,147,483,647
无符号整数 2 或 4 字节 0 至 65,535 或 0 至 4,294,967,295
短的 2字节 -32,768 至 32,767
无符号短 2字节 0 至 65,535
长的 4字节 -2,147,483,648 至 2,147,483,647
无符号长 4字节 0 至 4,294,967,295

要获取特定平台上类型或变量的确切大小,可以使用sizeof运算符。表达式sizeof(type)生成对象或类型的存储大小(以字节为单位)。以下是在任何机器上获取 int 类型大小的示例 -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for int : %d \n", sizeof(int));
   return 0;
}

当您编译并执行上述程序时,它会在 Linux 上产生以下结果 -

2013-09-07 22:21:39.155 demo[1340] Storage size for int : 4 

浮点类型

下表为您提供了有关标准浮点类型的详细信息,包括存储大小、值范围及其精度 -

类型 存储大小 取值范围 精确
漂浮 4字节 1.2E-38 至 3.4E+38 小数点后 6 位
双倍的 8字节 2.3E-308至1.7E+308 小数点后 15 位
长双 10字节 3.4E-4932 至 1.1E+4932 小数点后 19 位

头文件 float.h 定义了宏,允许您在程序中使用这些值以及有关实数二进制表示形式的其他详细信息。以下示例将打印浮点类型及其范围值占用的存储空间 -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Storage size for float : %d \n", sizeof(float));
   return 0;
}

当您编译并执行上述程序时,它会在 Linux 上产生以下结果 -

2013-09-07 22:22:21.729 demo[3927] Storage size for float : 4 

虚空类型

void 类型指定没有可用值。它用于三种情况 -

先生。 类型和描述
1 函数返回 void

Objective-C 中有多种函数不返回值,或者可以说它们返回 void。无返回值的函数的返回类型为 void。例如,void exit(int status);

2 函数参数为 void

Objective-C 中有多种不接受任何参数的函数。没有参数的函数可以接受 void。例如,int rand(void);

此时您可能不理解 void 类型,所以让我们继续,我们将在接下来的章节中介绍这些概念。

Objective-C 变量

变量只不过是我们的程序可以操作的存储区域的名称。Objective-C中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局;该内存中可以存储的值的范围;以及可以应用于变量的操作集。

变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写和小写字母是不同的,因为 Objective-C 区分大小写。基于上一章解释的基本类型,将有以下基本变量类型 -

先生。 类型和描述
1

字符

通常是一个八位位组(一个字节)。这是一个整数类型。

2

整数

机器最自然的整数大小。

3

漂浮

单精度浮点值。

4

双倍的

双精度浮点值。

5

空白

代表没有类型。

Objective-C 编程语言还允许定义各种其他类型的变量,我们将在后续章节中介绍这些变量,例如枚举、指针、数组、结构体、联合等。在本章中,我们只研究基本变量类型。

Objective-C 中的变量定义

变量定义意味着告诉编译器在哪里以及为变量创建存储空间的大小。变量定义指定一种数据类型并包含该类型的一个或多个变量的列表,如下所示 -

type variable_list;

这里,type必须是有效的 Objective-C 数据类型,包括 char、w_char、int、float、double、bool 或任何用户定义的对象等,variable_list可以由一个或多个以逗号分隔的标识符名称组成。这里显示了一些有效的声明 -

int    i, j, k;
char   c, ch;
float  f, salary;
double d;

该行int i, j, k; 两者都声明并定义了变量 i、j 和 k;它指示编译器创建名为 i、j 和 k 的 int 类型变量。

变量可以在其声明中初始化(分配初始值)。初始化器由一个等号后跟一个常量表达式组成,如下所示 -

type variable_name = value;

一些例子是 -

extern int d = 3, f = 5;    // declaration of d and f. 
int d = 3, f = 5;           // definition and initializing d and f. 
byte z = 22;                // definition and initializes z. 
char x = 'x';               // the variable x has the value 'x'.

对于没有初始化器的定义:具有静态存储持续时间的变量隐式初始化为 NULL(所有字节的值为 0);所有其他变量的初始值未定义。

Objective-C 中的变量声明

变量声明向编译器保证存在一个具有给定类型和名称的变量,以便编译器继续进行进一步编译,而无需有关该变量的完整详细信息。变量声明仅在编译时才有意义,编译器在程序链接时需要实际的变量声明。

当您使用多个文件并且在其中一个文件中定义变量时,变量声明非常有用,该文件在链接程序时可用。您将在任何地方使用extern关键字声明变量。虽然您可以在 Objective-C 程序中多次声明一个变量,但它只能在一个文件、函数或代码块中定义一次。

例子

尝试以下示例,其中变量已在顶部声明,但它们已在主函数内定义和初始化 -

#import <Foundation/Foundation.h>

// Variable declaration:
extern int a, b;
extern int c;
extern float f;

int main () {
  /* variable definition: */
  int a, b;
  int c;
  float f;
 
  /* actual initialization */
  a = 10;
  b = 20;
  
  c = a + b;
  NSLog(@"value of c : %d \n", c);

  f = 70.0/3.0;
  NSLog(@"value of f : %f \n", f);
 
  return 0;
}

当上面的代码被编译并执行时,它会产生以下结果 -

2013-09-07 22:43:31.695 demo[14019] value of c : 30 
2013-09-07 22:43:31.695 demo[14019] value of f : 23.333334 

同样的概念适用于函数声明,您在声明时提供函数名称,而其实际定义可以在其他任何地方给出。在下面的示例中,使用 C 函数进行了解释,正如您所知,Objective-C 也支持 C 风格函数 -

// function declaration
int func();

int main() {
   // function call
   int i = func();
}

// function definition
int func() {
   return 0;
}

Objective-C 中的左值和右值

Objective-C 中有两种表达式 -

  • 左值- 引用内存位置的表达式称为“左值”表达式。左值可以显示为赋值的左侧或右侧。

  • 右值- 术语右值是指存储在内存中某个地址的数据值。右值是一个不能赋值的表达式,这意味着右值可以出现在赋值的右侧,但不能出现在左侧。

变量是左值,因此可能出现在赋值的左侧。数字文字是右值,因此不能被赋值,也不能出现在左侧。以下是有效的声明 -

int g = 20;

但以下不是有效的语句,会生成编译时错误 -

10 = 20;

Objective-C 常量

常量是指程序在执行过程中不得更改的固定值。这些固定值也称为文字

常量可以是任何基本数据类型,例如整型常量、浮点常量、字符常量或字符串常量。还有枚举常量。

常量处理方式与常规变量一样,只是它们的值在定义后不能修改。

整数文字

整数文字可以是十进制、八进制或十六进制常量。前缀指定基数或基数:0x 或 0X 表示十六进制,0 表示八进制,没有任何内容表示十进制。

整数文字还可以具有 U 和 L 的组合后缀,分别表示无符号和长整型。后缀可以是大写或小写,并且可以是任何顺序。

以下是整数文字的一些示例 -

212         /* Legal */
215u        /* Legal */
0xFeeL      /* Legal */
078         /* Illegal: 8 is not an octal digit */
032UU       /* Illegal: cannot repeat a suffix */

以下是各种类型整数文字的其他示例 -

85         /* decimal */
0213       /* octal */
0x4b       /* hexadecimal */
30         /* int */
30u        /* unsigned int */
30l        /* long */
30ul       /* unsigned long */

浮点文字

浮点文字具有整数部分、小数点、小数部分和指数部分。您可以用十进制形式或指数形式表示浮点文字。

使用小数形式表示时,必须包含小数点、指数或两者;使用指数形式表示时,必须包含整数部分、小数部分或两者。带符号指数由 e 或 E 引入。

以下是浮点文字的一些示例 -

3.14159       /* Legal */
314159E-5L    /* Legal */
510E          /* Illegal: incomplete exponent */
210f          /* Illegal: no decimal or exponent */
.e55          /* Illegal: missing integer or fraction */

字符常量

字符文字用单引号括起来,例如“x”,并且可以存储在char类型的简单变量中。

字符文字可以是普通字符(例如“x”)、转义序列(例如“\t”)或通用字符(例如“\u02C0”)。

C 中的某些字符在以反斜杠开头时将具有特殊含义,它们用于表示换行符 (\n) 或制表符 (\t)。在这里,您有一些此类转义序列代码的列表 -

转义序列 意义
\\ \ 特点
\' ' 特点
\" “ 特点
\? ?特点
\A 警报或铃声
\b 退格键
\F 换页
\n 新队
\r 回车符
\t 水平制表符
\v 垂直标签
\呜呜 一到三位数的八进制数
\xhh 。。。 一位或多位数字的十六进制数

以下是显示一些转义序列字符的示例 -

#import <Foundation/Foundation.h>

int main() {
   NSLog(@"Hello\tWorld\n\n");
   return 0;
}

当上面的代码被编译并执行时,它会产生以下结果 -

2013-09-07 22:17:17.923 demo[17871] Hello	World

字符串文字

字符串文字或常量用双引号“”括起来。字符串包含与字符文字类似的字符:普通字符、转义序列和通用字符。

您可以使用字符串文字将长行分成多行,并使用空格分隔它们。

以下是字符串文字的一些示例。所有三种形式都是相同的字符串。

"hello, dear"

"hello, \

dear"

"hello, " "d" "ear"

定义常量

C 中有两种简单的方法来定义常量 -

  • 使用#define预处理器。

  • 使用const关键字。

#define 预处理器

以下是使用 #define 预处理器定义常量的形式 -

#define identifier value

下面的例子详细解释了它 -

#import <Foundation/Foundation.h>

#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'

int main() {
   int area;
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

当上面的代码被编译并执行时,它会产生以下结果 -

2013-09-07 22:18:16.637 demo[21460] value of area : 50
2013-09-07 22:18:16.638 demo[21460] 

const 关键字

您可以使用const前缀来声明特定类型的常量,如下所示 -

const type variable = value;

下面的例子详细解释了它 -

#import <Foundation/Foundation.h>

int main() {
   const int  LENGTH = 10;
   const int  WIDTH  = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   NSLog(@"value of area : %d", area);
   NSLog(@"%c", NEWLINE);

   return 0;
}

当上面的代码被编译并执行时,它会产生以下结果 -

2013-09-07 22:19:24.780 demo[25621] value of area : 50
2013-09-07 22:19:24.781 demo[25621] 

请注意,以大写字母定义常量是一种良好的编程习惯。

Objective-C 运算符

运算符是告诉编译器执行特定数学或逻辑操作的符号。Objective-C 语言具有丰富的内置运算符,并提供以下类型的运算符 -

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 按位运算符
  • 赋值运算符
  • 杂项运算符

本教程将一一讲解算术、关系、逻辑、位、赋值等运算符。

算术运算符

下表列出了 Objective-C 语言支持的所有算术运算符。假设变量A为 10,变量B为 20,则 -

显示示例

操作员 描述 例子
+ 添加两个操作数 A + B 将为 30
- 从第一个操作数中减去第二个操作数 A - B 将给出 -10
* 将两个操作数相乘 A * B 将给出 200
/ 分子除以分母 B/A 将给出 2
% 模数运算符和整数除法后的余数 B % A 将给出 0
++ 自增运算符将整数值加一 A++ 会给出 11
-- 自减运算符将整数值减一 A-- 会给 9

关系运算符

下表列出了 Objective-C 语言支持的所有关系运算符。假设变量A为 10,变量B为 20,则 -

显示示例

操作员 描述 例子
== 检查两个操作数的值是否相等;如果是,则条件成立。 (A == B) 不正确。
!= 检查两个操作数的值是否相等;如果值不相等,则条件为真。 (A != B) 为真。
> 检查左操作数的值是否大于右操作数的值;如果是,则条件成立。 (A > B) 不正确。
< 检查左操作数的值是否小于右操作数的值;如果是,则条件成立。 (A < B) 为真。
>= 检查左操作数的值是否大于或等于右操作数的值;如果是,则条件成立。 (A >= B) 不正确。
<= 检查左操作数的值是否小于或等于右操作数的值;如果是,则条件成立。 (A <= B) 为真。

逻辑运算符

下表列出了 Objective-C 语言支持的所有逻辑运算符。假设变量A为 1,变量B为 0,则 -

显示示例

操作员 描述 例子
&& 称为逻辑与运算符。如果两个操作数都不为零,则条件为真。 (A && B) 是错误的。
|| 称为逻辑或运算符。如果两个操作数中的任何一个不为零,则条件为真。 (A || B) 为真。
称为逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为 true,则逻辑 NOT 运算符将使 false。 !(A && B) 为真。

按位运算符

位运算符作用于位并执行逐位运算。&、| 和 ^ 的真值表如下 -

p q 质与问 p| q p^q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

假设A = 60;B=13;现在以二进制格式,它们将如下 -

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

〜A = 1100 0011

Objective-C 语言支持的按位运算符如下表所示。假设变量 A 为 60,变量 B 为 13,则 -

显示示例

操作员 描述 例子
& 如果两个操作数中都存在,则二进制 AND 运算符会将一位复制到结果中。 (A & B) 将给出 12,即 0000 1100
| 如果任一操作数中存在该位,则二元或运算符会复制该位。 (A | B) 将给出 61,即 0011 1101
^ 如果在一个操作数中设置了该位,但不是在两个操作数中都设置了该位,则二进制 XOR 运算符会复制该位。 (A ^ B) 将给出 49,即 0011 0001
二进制补码运算符是一元的,具有“翻转”位的效果。 (~A ) 将给出 -61,即 2 的补码形式的 1100 0011。
<< 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 A << 2 将给出 240,即 1111 0000
>> 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 A >> 2 将得到 15,即 0000 1111

赋值运算符

Objective-C 语言支持以下赋值运算符 -

显示示例

操作员 描述 例子
= 简单赋值运算符,将右侧操作数的值分配给左侧操作数 C = A + B 将 A + B 的值赋给 C
+= 添加AND赋值运算符,它将右操作数添加到左操作数并将结果分配给左操作数 C += A 等价于 C = C + A
-= 减法与赋值运算符,它从左操作数中减去右操作数,并将结果赋给左操作数 C -= A 相当于 C = C - A
*= 乘法与赋值运算符,将右操作数与左操作数相乘,并将结果赋给左操作数 C *= A 相当于 C = C * A
/= 除法与赋值运算符,它将左操作数与右操作数相除,并将结果赋给左操作数 C /= A 相当于 C = C / A
%= 模数与赋值运算符,它使用两个操作数取模并将结果分配给左操作数 C %= A 相当于 C = C % A
<<= 左移 AND 赋值运算符 C <<= 2 与 C = C << 2 相同
>>= 右移 AND 赋值运算符 C >>= 2 与 C = C >> 2 相同
&= 按位与赋值运算符 C &= 2 与 C = C & 2 相同
^= 按位异或和赋值运算符 C ^= 2 与 C = C ^ 2 相同
|= 按位 OR 和赋值运算符 C |= 2 与 C = C | 相同 2

其他运算符 ↦ sizeof 和三元

还有一些其他重要的运算符,包括sizeof? : 由 Objective-C 语言支持。

显示示例

操作员 描述 例子
大小() 返回变量的大小。 sizeof(a),其中 a 是整数,将返回 4。
& 返回变量的地址。 &A; 将给出变量的实际地址。
* 指向变量的指针。 *A; 将指向一个变量。
?: 条件表达式 如果条件为真?然后值 X :否则值 Y

Objective-C 中的运算符优先级

运算符优先级决定表达式中术语的分组。这会影响表达式的计算方式。某些运算符的优先级高于其他运算符;例如,乘法运算符的优先级高于加法运算符 -

例如,x = 7 + 3 * 2;此处,x 被分配为 13,而不是 20,因为运算符 * 的优先级高于 +,因此它首先乘以 3*2,然后添加到 7。

在这里,优先级最高的运算符出现在表的顶部,优先级最低的运算符出现在底部。在表达式中,将首先计算优先级较高的运算符。

类别  操作员  关联性 
后缀  () [] -> . ++ - -   左到右 
一元  + - ! ~ ++ - - (类型)* & sizeof  右到左 
乘法   * / %  左到右 
添加剂   + -  左到右 
转移   <<>>  左到右 
关系型   <<=>>=  左到右 
平等   ==!=  左到右 
按位异或  左到右 
按位或  左到右 
逻辑与  &&  左到右 
逻辑或  ||  左到右 
有条件的  ?:  右到左 
任务  = += -= *= /= %=>>= <<= &= ^= |=  右到左 
逗号  左到右 

Objective-C 循环

可能存在一种情况,当您需要多次执行一段代码时。一般来说,语句是按顺序执行的:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

编程语言提供了各种控制结构,允许更复杂的执行路径。

循环语句允许我们多次执行一条语句或一组语句,以下是大多数编程语言中循环语句的一般形式 -

循环架构

Objective-C 编程语言提供以下类型的循环来处理循环需求。单击以下链接查看其详细信息。

先生。 循环类型和描述
1 while 循环

当给定条件为真时,重复一个语句或一组语句。它在执行循环体之前测试条件。

2 for循环

多次执行一系列语句并缩写管理循环变量的代码。

3 do...while 循环

与 while 语句类似,只不过它测试循环体末尾的条件。

4 嵌套循环

您可以在任何另一个 while、for 或 do..while 循环中使用一个或多个循环。

循环控制语句

循环控制语句改变其正常顺序的执行。当执行离开作用域时,在该作用域中创建的所有自动对象都将被销毁。

Objective-C 支持以下控制语句。单击以下链接查看其详细信息。

先生。 控制语句和描述
1 中断语句

终止循环switch语句并将执行转移到紧随循环或 switch 之后的语句。

2 继续声明

导致循环跳过其主体的其余部分并在重复之前立即重新测试其条件。

无限循环

如果条件永远不会变为假,则循环将成为无限循环。for循环传统上用于此目的。由于构成 for 循环的三个表达式都不是必需的,因此您可以通过将条件表达式留空来创建无限循环。

#import <Foundation/Foundation.h>
 
int main () {

   for( ; ; ) {
      NSLog(@"This loop will run forever.\n");
   }

   return 0;
}

当条件表达式不存在时,假定为真。您可能有一个初始化和增量表达式,但 Objective-C 程序员更常用 for(;;) 构造来表示无限循环。

Objective-C 决策

决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及如果确定条件为真则要执行的一个或多个语句,以及可选地如果条件确定则要执行的其他语句确定为假。

以下是大多数编程语言中典型决策结构的一般形式 -

Objective-C 中的决策语句

Objective-C 编程语言将任何非零非空值假定为true,如果它为零null 则将其假定为false值。

Objective-C 编程语言提供以下类型的决策语句。单击以下链接查看其详细信息 -

先生。 声明及说明
1 if 语句

if语句由一个布尔表达式后跟一个或多个语句组成。

2 if...else 语句

if语句后面可以跟一个可选的else 语句,该语句在布尔表达式为 false 时执行。

3 嵌套 if 语句

您可以在另一个ifelse if语句中使用一个ifelse if语句。

4 switch语句

switch语句允许测试变量是否与值列表相等

5 嵌套 switch 语句

您可以在另一个switch语句中使用一个switch语句。

这 ?: 操作员

我们已经介绍了条件运算符 ? :在上一章中可以用来替换if...else语句。它具有以下一般形式 -

Exp1 ? Exp2 : Exp3;

其中 Exp1、Exp2 和 Exp3 是表达式。注意冒号的使用和位置。

的值?表达式的确定如下:Exp1 被求值。如果为真,则计算 Exp2 并成为整个 ? 的值。表达。如果 Exp1 为 false,则计算 Exp3 并且其值成为表达式的值。

Objective-C 函数

函数是一组共同执行任务的语句。每个 Objective-C 程序都有一个 C 函数,即main(),并且所有最简单的程序都可以定义附加函数。

您可以将代码划分为单独的函数。如何在不同的函数之间划分代码取决于您,但逻辑上的划分通常是让每个函数执行特定的任务。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

基本上在 Objective-C 中,我们将函数称为方法。

Objective-C 基础框架提供了许多您的程序可以调用的内置方法。例如,方法appendString()将字符串附加到另一个字符串。

方法有多种名称,如函数、子例程或过程等。

定义方法

Objective-C 编程语言中方法定义的一般形式如下 -

- (return_type) method_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen {
   body of the function
}

Objective-C 编程语言中的方法定义由方法头方法体组成。以下是方法的所有部分 -

  • 返回类型- 方法可以返回一个值。return_type是函数返回值的数据类型有些方法执行所需的操作而不返回值。在本例中, return_type 是关键字void

  • 方法名称- 这是方法的实际名称。方法名和参数列表共同构成方法签名。

  • 参数- 参数就像占位符。当调用函数时,您将一个值传递给参数。该值称为实际参数或参数。参数列表是指方法的参数的类型、顺序和数量。参数是可选的;也就是说,方法可以不包含参数。

  • 连接参数- 连接参数是为了使其更易于阅读并在调用时使其清晰。

  • 方法体- 方法体包含定义该方法功能的语句集合。

例子

以下是名为max()的方法的源代码。此方法采用两个参数 num1 和 num2 并返回两者之间的最大值 -

/* function returning the max between two numbers */
- (int) max:(int) num1 secondNumber:(int) num2 {
   
   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

方法声明

方法声明告诉编译器函数名称以及如何调用该方法。函数的实际主体可以单独定义。

方法声明包含以下部分 -

- (return_type) function_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... 
joiningArgumentn:( argumentTypen )argumentNamen;

对于上面定义的函数 max(),以下是方法声明 -

-(int) max:(int)num1 andNum2:(int)num2;

当您在一个源文件中定义方法并在另一文件中调用该方法时,需要方法声明。在这种情况下,您应该在调用该函数的文件顶部声明该函数。

调用方法

创建 Objective-C 方法时,您需要定义该函数必须执行的操作。要使用方法,您必须调用该函数来执行定义的任务。

当程序调用函数时,程序控制权将转移到被调用的方法。被调用的方法执行定义的任务,并且当执行其返回语句或到达其函数结束右大括号时,它将程序控制权返回给主程序。

要调用方法,您只需传递所需的参数和方法名称,如果方法返回一个值,那么您可以存储返回值。例如 -

#import <Foundation/Foundation.h>

@interface SampleClass:NSObject
/* method declaration */
- (int)max:(int)num1 andNum2:(int)num2;
@end

@implementation SampleClass

/* method returning the max between two numbers */
- (int)max:(int)num1 andNum2:(int)num2 {

   /* local variable declaration */
   int result;
 
   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }
 
   return result; 
}

@end

int main () {
   
   /* local variable definition */
   int a = 100;
   int b = 200;
   int ret;
   
   SampleClass *sampleClass = [[SampleClass alloc]init];

   /* calling a method to get max value */
   ret = [sampleClass max:a andNum2:b];
 
   NSLog(@"Max value is : %d\n", ret );
   return 0;
}

我保留了 max() 函数和 main() 函数并编译了源代码。运行最终的可执行文件时,它将产生以下结果 -

2013-09-07 22:28:45.912 demo[26080] Max value is : 200

函数参数

如果函数要使用参数,则它必须声明接受参数值的变量。这些变量称为函数的形式参数。

形式参数的Behave与函数内的其他局部变量类似,在进入函数时创建并在退出时销毁。

调用函数时,可以通过两种方式将参数传递给函数 -

先生。 呼叫类型和描述
1 按值调用

此方法将参数的实际值复制到函数的形式参数中。在这种情况下,对函数内部参数所做的更改不会对参数产生影响。

2 通过参考调用

此方法将参数的地址复制到形式参数中。在函数内部,地址用于访问调用中使用的实际参数。这意味着对参数所做的更改会影响参数。

默认情况下,Objective-C 使用按值调用来传递参数。一般来说,这意味着函数中的代码不能更改用于调用该函数的参数,并且上述示例在调用 max() 函数时使用了相同的方法。

Objective-C 块

Objective-C 类定义了一个将数据与相关Behave组合在一起的对象。有时,仅表示单个任务或Behave单元是有意义的,而不是方法的集合。

块是添加到 C、Objective-C 和 C++ 中的语言级功能,它允许您创建不同的代码段,这些代码段可以像值一样传递给方法或函数。块是 Objective-C 对象,这意味着它们可以添加到 NSArray 或 NSDictionary 等集合中。它们还能够从封闭范围捕获值,这使得它们类似于其他编程语言中的闭包或 lambda

简单的块声明语法

returntype (^blockName)(argumentType);

简单的块实现

returntype (^blockName)(argumentType)= ^{
};

这是一个简单的例子

void (^simpleBlock)(void) = ^{
   NSLog(@"This is a block");
};

我们可以使用调用该块

simpleBlock();

块接受参数和返回值

块也可以像方法和函数一样接受参数并返回值。

这是一个简单的示例,用于实现和调用带有参数和返回值的块