ObjectiveC-06-循环、逻辑控制、异常处理和程序预处理

2024-03-31 21:12

本文主要是介绍ObjectiveC-06-循环、逻辑控制、异常处理和程序预处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节详细讲解下程序运行过程中的逻辑控制指令,主要有if等,但在Objective-C中添加了预编译处理指令,这是一个新的内容需要仔细研究下。这节的内容比较简单,但需要多加练习。

循环结构

在ObjC中主要有for、while和do这三种循环结构,do是do while的组合(一般不太常用),一般适合在结尾处开始执行时才用do while语句。

在循环执行代码时可搭配 break 和 continue 语句同时使用;

for

最简单的一种集合循环模式,语法结构for( int =0; condition; exp)。

//for, 除了以下常规的for写法,还有for...in操作int sum = 0;for (int n=1; n<10; n++){sum += n;}NSLog(@"sum is %i", sum);//while        int count=1;while(count<=5){count++;}
//do whileint count=1;do{count++;} while (number<=5)       

for in

这种是一种iterator(迭代器)模式,它与上面的不同之处在于简单,缺点是不能得到循环时的索引值,需要额外定义,在ObjectiveC中很多集合类型都实现了iterator模式。

//初始多个元素的数组
NSArray *myArray = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4",nil];//以字符串遍历
for(NSString *item in myArray ){NSLog(@"this is an element of myArray %@", item);
}//2024-03-31 18:50:18.022629+0800 helloWorld[24475:1026265] 1
//2024-03-31 18:50:18.022917+0800 helloWorld[24475:1026265] 2
//2024-03-31 18:50:18.022948+0800 helloWorld[24475:1026265] 3
//2024-03-31 18:50:18.022968+0800 helloWorld[24475:1026265] 4

选择结构

选择就用字面量if关键字来表示,有如下几种格式:

  • if:一般常用于参数验证
  • if…else:双条件处理,除了A全是B
  • if …else if…else:多条件处理,除了A,B,C外全是D,如果if太多可考虑用switch来代替

if比较简单就不多举例子了,可以按上面三种模式多多练习一下。

if else if else

//**if else if else **
if ( expression1 ){}else if( expression2 ){}else{}

switch

switch可接受int、char、enum。示例如下:

//**switch case**
int flag = 1;
switch(flag){case v1:break;case v2:break;default:break;
}

中断处理

主要包括:return、breadk、continue三种。这三种其实不太好起名字,暂时就叫中断吧,这几种都可用于循环和选择结构中。

return

返回,主要使用场景有两种,一种是可用于方法返回值,另一种是方法的参数验证,比如:

NSString *iftetst(int i){if (i<=5){//参数验证return NULL; }return @"";//方法返回
}

break, continue

用于循环中断,也可以用于switch(多if其实也是循环的一种),示例代码如下:

        NSArray *myArray = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4",nil];//初始多个元素的数组//以字符串遍历,当遇到长度小于4的字符串时直接跳出整个循环for(NSString *item in myArray ){if(item.length<4){break;}NSLog(@"%@", item);}//以字符串遍历,当遇到长度小于4的字符串时直接跳出这次循环,继续下一个循环for(NSString *item in myArray ){if(item.length<4){continue;;}NSLog(@"%@", item);}

异常处理

Cocoa中使用NSException类来表示异常,通常在大型程序开发过程中要封装多个与业务相关的异常,这些异常都必须继承上述的NSException类。APP是否允许异常也可以在Building settings中进行设置。
在这里插入图片描述

关键字

可用的异常处理

  1. @try:定义可抛出异常的代码块
  2. @catch:捕获获常,可以存在多个
  3. @finally:无论是否抛出异常,这段代码都会执行,一般用于资源释放
  4. @throw:在代码中手动抛出异常

捕获异常

@try{Complex *c3 = [Complex class];c3.print;
}@catch(NSException *e){e.reason;
}@finally{e.reason;
}2023-12-20 21:57:17.399690+0800 FractionTest[35583:5256761] +[Complex print]: unrecognized selector sent to class 0x1000087a8
2023-12-20 21:57:17.399889+0800 FractionTest[35583:5256761]  yes

抛出异常

void exceptionTest(){NSException *e = [NSException exceptionWithName:@"" reason:@"" userInfo:[NSNull null]];//方式一,通用@throw  e;//方式二,只对NSException有效[e raise];
}

捕获后抛出

@try{Complex *c3 = [Complex class];c3.print;
}@catch(NSException *e){@throw; //这里不必指定e变量
}

程序预处理

主要是为了方便代码开发、移植和兼容等场景,ObjC中固化的一些特殊代码,这些特殊代码是编译过程的一部分,会在正式程序运行之前优先处理,使用 # 来标记,且在程序文件中必须是行的第一个字母。

typedof 设置别名

如果一个类或变量名字比较长或是特殊时,为当前的数据类型指派另一个名称。 typedof定义的别名只在本类中生效,如果想设计成全局生效,可以使用#define来定义,typeof示例如下:

//原生的 int a; 变量声明可用下面两行来代替
typedof int Counter; //把原生的int关键字起了一个叫Counter的别名Counter a;
//把系统的Number重新起了一个叫NumberObject的API
typedef Number *NumberObject;NumberObject n1, n2, n3;
//枚举别名
typedof enum {january=1, february=2} Month;Month m1, m2;

#define 预定义名称

预定义名称,注意预定义的值不能在程序运行过程中被修改;一般位置在#import之后,命名也建议用全大写字母。

//定义了名称TRUE值为1,之后程序中任何出现TRUE字样的地方都会被替换为1
#define TRUE 1 
gameOver = TRUE; //gameOver==1#define EQUALS ==
if(y EQUALS 0){}

预定义的名称的值可以进行简单的运算。

#define TRUE 1 
#define A TRUE*2gameOver = A; //gameOver==2

带自变量的宏

//如果表达式太长了,可以在行尾加一个 \ 来换行,另外这个year是一个代码中的变量
#define IS_LEAP_YEAR year%4 == 0 && year%100 != 0 || year%400 == 0
if( IS_LEAP_YEAR ) {}//上面的方式可读性比较差,建议改成下面的方式,添加自变量,需要注意的是IS_LEAP_YEAR(y)名称和变量的括号之间没有空格
#define IS_LEAP_YEAR(y) y%4 == 0 && y%100 != 0 || y%400 == 0
if( IS_LEAP_YEAR(year) ) {}

更复杂的宏

#define MakeFract(x,y) ([[Fraction alloc] initWith: x over: y])Fraction *myFra = MakeFract(1, 2);

一个好的实践是把上面这些宏定义在一个单独的.h文件中,然后通过 #import 来引用。

//~~CONST.h
#define TRUE 1
#define FALSE 0//~~Front.m
#import "CONST.h"
gameOver = TRUE;

#ifdef 预编译处理

条件定义

主要包括 #ifndef、#define、 #ifdef、#else 、#endif 这几个语句,这几个语句主要用于同一套代码在不同的设备上运行时的差异化设置。可混在正常代码方法中,不限位置。一个简单的官方例子:

#ifndef Complex_h
#define Complex_h#import <Foundation/Foundation.h>
@interface Complex : NSObject
@end#endif /* Complex_h */

在同一个代码中可以出现多个条件块,比如NSString.h接口

#if !defined(_OBJC_UNICHAR_H_)
#define _OBJC_UNICHAR_H_
#endif#define NS_UNICHAR_IS_EIGHT_BIT 0NS_SWIFT_UNAVAILABLE("Use String or NSString instead.")
@interface NSSimpleCString : NSString {
@packagechar *bytes;int numBytes;#if __LP64__int _unused;
#endif
}

自定义条件

自定义条件编译逻辑,比如应用的代码如下,IPAD为自定义的变量值,在程序中按如下方法使用。

- (id) initWithCoder: (NSCoder *) decoder{#ifdef IPADNSLog(@"AAA");#endifreturn (self);
} 

如果想使上述代码存在意义,可采用三种运行方法:

  • 定义方式1:在某个类中定义
#define IPAD 1
  • 定义方式2:在xcode中定义,位置 Build Settings

在这里插入图片描述

  • 定义方式3:在命令行启动时定义
clang -fobjc -arc -D IPAD main.m -

#if 和 #else 条件判断

可加一些逻辑判断,比如值比较。

#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define NSMaximumStringLength (INT MAX-1)
#endif
#if IPAD>0
#define imageFile @"barHD.png"
#endif

另外一点#ifdef,其实就是#if+#defined的缩写形式,比如:

#if defined(_OBJC_UNICHAR_H_)
#if !defined(_OBJC_UNICHAR_H_)

解除定义

用于消除某些已定义的语句,比如下列代码,如果之前定义了IPAD,之后用undef消除了,则程序不会报错,但所有判断的地方全变为了false。

#undef IPAD 

至此,ObjectiveC语言的基础部分就全部讲述完了,如果能掌握这几章的内容,那么应该可以写一些稍复杂的程序了,比如计算器、数据统计、人机问答(非AI)。后续将讲述一些高级内容,这些高级内容完全是依赖基础的,需要先把基础打牢,尤其是讲到的语法和关键字。

这篇关于ObjectiveC-06-循环、逻辑控制、异常处理和程序预处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/865354

相关文章

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

JAVA中while循环的使用与注意事项

《JAVA中while循环的使用与注意事项》:本文主要介绍while循环在编程中的应用,包括其基本结构、语句示例、适用场景以及注意事项,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录while循环1. 什么是while循环2. while循环的语句3.while循环的适用场景以及优势4. 注意

Python中异常类型ValueError使用方法与场景

《Python中异常类型ValueError使用方法与场景》:本文主要介绍Python中的ValueError异常类型,它在处理不合适的值时抛出,并提供如何有效使用ValueError的建议,文中... 目录前言什么是 ValueError?什么时候会用到 ValueError?场景 1: 转换数据类型场景

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1