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

相关文章

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现