ObjectiveC-03-XCode的使用和基础数据类型

本节做为Objective-C的入门课程,笔者会从零基础开始介绍这种程序设计语言的各个方面。

术语

  • ObjeC:Objective-C的简称,因为完整的名称过长,后续会经缩写来代替;
  • 项目/工程:也称工程,指的是一个App的源文件的文件夹包和结构,有时也称为工程或项目工程。
  • 项目模板:不只ObjC,用不同编程语言开发App时其源码都会包含源文件、集成框架、配置文件、资源图片等,这些元素需要放在同一个文件中并要符合某种规则,而针对不同类型的App其元素和组织又不一样,这个工作比较费时,所以为了效率考虑一般会经一个母版进行修改,这个母版就称为项目模板;

Command Line Tool工程

首先,我们需要创建一个Command line tool工程项目(即不带图形化界面的项目)。
在这里插入图片描述
在上述工程创建界面上有很多模板项目,可以按需要选择相应的模板开发,这样省去了好多搭建框架的时间,但也可以选择从空项目开始。多数模板可以从字面意思就可以了解。

  • 现在我们只需要知道Command Line Tool工程模板就足够了(一种无UI界面的可在命令行执行的脚本工程模板);
  • 后续在涉及AppKit之前的所有代码我们全会以这类工程为载体演示代码,其它的工程模板在讲到其内容时再详细解释。

创建HelloWorld工程

按照惯例,我们还是以一个Hello Word项目做为开始,了解一下ObjC(ObjectiveC简称)项目结构和基础语法。项目名称暂时称为helloWorld,项目设置采用默认即可,不需要做任何改变,项目结构如下:

在这里插入图片描述

打开main.m文件,我们所有的测试代码暂时全写在这里面,.m是ObjC代码文件的后缀(.c是C语言的源码文件),运行时会交由程序编译器LLVM处理和运行。

//
//  main.m
//  helloWorld
//
//  Created by 刘东 on 2023/12/20.
//#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {@autoreleasepool { // 自动释放池,由系统来管理变量的内存// insert code here...NSLog(@"Hello, World!"); // 打包日志函数,用@修饰表示NSString对象}return 0;  // 规定 0 表示程序正常结束,其它值都是非正常结束
}

除了上述.m文件外还可以兼容几下以类源码文件:

  1. .c:C文件
  2. .cc, .cpp:C++文件
  3. .h:头文件
  4. .mm:Objective-C++文件,可以同时使用ObjectiveC和C++语法;
  5. .pl:Perl文件
  6. .o:ObjectiveC编译后的文件
  7. .m:Objective-c文件

代码注释

在ObjC中只有两种注释:

  • //:行注释,一般用于代码行或代码后面;
  • /* */:块注释,一般用于类说明,方法说明或代码块说明使用;
  • #pragma mark *** String funnel methods ***,这是一种特殊格式的指令,也能起到注释的作用,详细可参考代码导航一节;
// Secondary text that may be displayed/*Secondary text that may be displayed adjacent to or below the primary title depending on the configuration of the window.A value of empty string will remove the subtitle from the window layout.
*/

模块导入

格式为:#import <Foundation/Foundation.h> 注意最后面没有;分号,表示为当前类的实现添加相关的模块依赖。如果导入的是自定义的实现,则需要用双引号(本地)替换<>(系统)。

#import <Foundation/Foundation.h>
#import "Fraction.h" 

上述所谓的系统其实称为框架更合适,比如Foundation、AppKit框架,每个框架都有一个主头文件,它包含了框架内所有的头文件,只需导入一次就可以使用此框架内所有的功能,这样就省去了一个个导入的麻烦。

MAC OS所有框架的目录位于 /System/Library/Frameworks 目录下。

入口函数main

程序运行的主入口函数,格式为:int main(int argc, const char * argv[]),程序的执行入口和java的main函数功能相同,每个App最多只能允许存在一个main函数。一般练习时用main函数调用就行,如果是大型项目ObjC也提供了专门的单元测试框架,后续会讲到,main.m语法格式如下:

static void method(){
}/*
argc:命令行输入的参数个数
argcv:字符指针数组,即参数值
*/
int main(int argc, const char * argv[]) {@autoreleasepool {//代码位置}return 0;
}

运行传参

函数说明:int main(int argc, const char * argv[])

  • argc:命令行输入的参数个数
  • argcv:字符指针数组,即参数值,argcv[0]指向一个函数,argcv[1]为一个字符数组
int main(int argc, const char * argv[]) {@autoreleasepool {struct entry dict[100] = {{"abyss", "a bottomless pit"},{"addle", "to become confused"}};int entries = 10;int entryNumber;int lookup(struct entry dict[], char search[], int entries);if (argc!=2){NSLog(@"no word typed on the command line.");return 1;}entryNumber = lookup(dict, argv[1], entries);if(entryNumber!=-1){NSLog(@"%s", dict[entryNumber].definition);}}return 0;
}

调用方法如下,可从命令行,也可从Xcode中执行

clang -fobjc -arc main.m lookup abyss - 

上述程序会调用函数lookup,然后在dict字典中查找argv[1]中的单词,如果找到就返回详细的解释。

添加函数

在main函数所在的类中也可以添加自定义的方法,但方法的命名方式和ObjC的语法有很大不同,这一点需要额外注意。在main中定义的方法是C语言的语法。

#import <Foundation/Foundation.h>//无参方法,在方法前面也可以添加static关键字
void nsRangeTest(){NSRange range1 = {17, 4};
}//有参方法
NSComparisonResult *compareArray(id element, id compareEle){return [[compareEle name] compare: [element name]];
}int main(int argc, const char * argv[]) {@autoreleasepool {nsRangeTest();}return 0;
}

打印函数NSLog

打印函数,相当于C语言或JAVA语言的print()函数,这里需要注意写法,一定是以@开头,这也说明了NSLog函数的入参是一个NSString类型的对象(在ObjC语言中,字符串用@""表示),另外所有的Cocoa函数和对象全部以NS做为命名前缀(也被称命名空间),也有一些老的API是采用CF开头的但不建议使用了。

NSLog(@"Hello, World!");
int sum = 20+25;
NSLog(@"The sum is %i", sum); //NSLog函数如果发现%,则视为占位符,这样的占位符有很多,后续会讲到

也可以用printf()函数来代码,但不是太建议,因为NSLog添加了很多格式化的信息,注意看下面代码的输出

        NSLog(@"Hello, World!\n");printf("Hello, World!\n");~~~~2024-03-26 19:31:52.091265+0800 helloWorld[46546:5251675] Hello, World!Hello, World!

键盘输入

scanf()函数也可以使用占位符,因为键盘接收的原始数据全是字符串,在程序中需要做一些类型转换工作。下在程序运行后在scanf处会卡住,然后在控制台输入相应字符后就会往下执行了。

int main(int argc, const char * argv[]) {@autoreleasepool {int age;scanf("%i", &age); //注意&的用法,它表示一个指针引用,NSLog(@"age is %i", age);}return 0;
}/*~~
aaa
2024-03-27 14:39:56.103878+0800 objcBase[59017:6048518] age is 32759
Program ended with exit code: 0
*/

程序运行

除了使用Xcode工具运行,还可以使用命令行工具执行。其命令如下,其中prog1为重命名的项目名称。但这种方式并友好,因为还在设置PATH等资源目录。

(base) MacBook:~ liudong$ clang -fobjc-arc main.m -o prog1(base) MacBook:~ liudong$ clang -fobjc-arc -framework Foundation main.m -o prog1

输入类似下面的界面:
在这里插入图片描述
用NSLog输出时,上面的4596表示当前应用的进程ID号。另外编译好的文件一般会存放在以下目录中,其中helloWorld-ghwqfuwptpnvhtfpzqoxxzcbnzow是一串随机值。不同版本的OS操作系统存放的位置有可能不太一样。

~/Library/Developer/Xcode/DerivedData/helloWorld-ghwqfuwptpnvhtfpzqoxxzcbnzow/Build/Products/Debug

进入这个目录下可以执行./helloWorld就可以直接运行应用了。
在这里插入图片描述

程序中止

有两种方式一种是在main函数中中止,一种是在方法中强制中止,在main函数中直接使用retrun 0即可,则在方法中需要使用以下代码。

exit(0);

设置XCode

首先来讲,苹果公司通常喜欢在不同版本的XCode中增加或移动一些功能,而且这些功能对开发代码的效率是非常高的。下面就以XCode V13版本为例来说明下这些设置如何操作。

主界面

在这里插入图片描述

  • 导航器:用来显示项目的源码,最上面的有9个左右的工具栏,包括:符号、搜索、总是、调试、断点和日志等,快捷键盘是command+数字1~9;
  • 工具栏:这里最主要的是库面板,需要从菜单View-Show Toolbar打开;
  • 检查器:不同的文件会有不同的设置,也就是属性设置面板;
  • 代码编辑区:在最上面有一个面包屑栏和工具栏,工具栏上有导航文件功能,面包屑栏显示了当前文件一些内容。这块的功能比较简单,点一次就可以记住了;

环境下载

在Preferences偏好设置中可以下载不同的运行环境:
在这里插入图片描述

代码自动完成

XCode有代码提示功能,输入一个字符会有默认提示,通过ESC键来打开或关闭提示框,然后通过Control+/-可实现快速翻页。
在这里插入图片描述

  • # :代表define指令;
  • m :表示method;
  • f :表示函数;
  • c :表示类

代码导航

可以通过在源码中设置特殊的标识来把需要关心的代码加入到代码面包屑工具栏中,这些标识在编译时会被编译器忽略掉。
在这里插入图片描述
这些特殊标记通常用:

  1. -,减号实现一个分隔线,见上图
  2. whatever,任意字符;
  3. //开头的特殊标记,以关键字+冒号+空格+文字描述格式,比如//TODO: 未完成的工作,这些关键字一般有TODO:、FIXME:、!!!:、???:

快捷键

  1. 鼠标左键+option,然后点击某个类型,在弹出窗口点击相应的类型名可直接跳转到document;

  2. control+i,格式化代码;

  3. command+d,删除行(需要在keymap中搜索delete line自行设置);

  4. command+左/右箭头,快速移到行首和行尾

  5. command+shift+o,快速查找;

  6. command+option+左/右箭头:展开和折叠代码,功能们于Edit-Code Folding下面

  7. command+option+shift+左/右箭头:展开和折叠所有方法

  8. command+r,运行程序

  9. command+u,测试程序

另外可供编辑使用的快捷键盘就是电脑上的触摸屏,可通过Edit-Customizer Touch bar 来设置,如下:
在这里插入图片描述

程序调试

主要使用以下几个工具,依次是:跳到下一个断点、下一行、进入被调用的方法、跳出被调用的方法。分别对应快捷键F5~F8。

在这里插入图片描述

另一个调试窗口在导航区上,与调试区联动,主要是下图中这两个标签页,一个是性能查看,另一个是断点浏览
在这里插入图片描述
鼠标悬浮到某个程序变量上也会显示相应的信息
在这里插入图片描述
还有一些更高级的功能可以在控制台输入相应的指令,比如:

  • call [exp]:调用给定对象的方法;
  • print [exp]:打印表达式的原始值,比如print [int] [obj length];
  • print-object [exp]:打印表达式的对象值;
  • set [v] = [exp]:给表达式赋值;
  • whatis [exp]:判断变量的类型;
  • help:帮助;
    在这里插入图片描述

静态检查器

这个功能是不是一个新的功能,很多IDE都有此种能力,有些还会以插件的形式存在,比如sonna, understand或是idea中的各种分析插件。

静态检查器的功能就是不运行代码来分析代码中可能存在的一些问题,在xcode中其功能集中在菜单"project-Analyze"中,它可以检查代码中的:

  1. 安全问题;
  2. 并发问题;
  3. 逻辑问题;
  4. 冗余代码;
    在这里插入图片描述
    疑似有问题的代码可以在导航面板中查看,找到问题后可在面板中点Fix来修复这些警告信息。
    在这里插入图片描述
    有时也会误报,因为检查器毕竟也是一段逻辑固定的程序,没办法覆盖所有的代码模式,如果发现了语报除了用上面 Fix 来关闭外,也可以在方法后加一个特殊标识来告诉检查器这块的这个问题不要检查了,比如:
//类似这样的标签还有很多,可以按需选择
static void dataFun (void) NS_RETURNS_RETAINED {  }

基础数据类型

基础数据类型

布尔类型

关键字BOOL,其值默认只有YES或NO,在Objc中只可与1和0相互转换,占8位存储空间,在写程序时也可以用#define把TRUE和FALSE定义为1 和 0,示例如下:

BOOL areIn(int thing, int ti){if (thing == ti){return (YES);}return NO;//return thing = ti; 这行代码有问题,因为ObjC中只有0和1来平替YES和NO
}
NSString *bool2Str(BOOL y){if (y == YES){return @"yes";}else{return @"no";}
}
int main(int argc, const char * argv[]) {@autoreleasepool {BOOL *boolV = areIn(1, 2); NSLog(@"%d = %@", boolV, bool2Str(boolV)); //0 = noNSLog(@"%d = %@", 1, bool2Str(1)); //1 = yesNSLog(@"%d = %@", YES, bool2Str(YES)); //1 = yes}return 0;
}

char字符类型

单个字符,用’'单引号表示

char c = 'a';

int整数类型

int i = 1000;

float浮点类型

带小数点的变量,比如

float f = 123.95;

double双精度浮点数

双精度

double d = 8.44e+11;

字符串常量

字符不是一个基本类型,它是一个对象,在使用时除了用对象实例化后,简单的可以直接用@“”,来表示:

NSString *str = @"korgs";
创建一个可变字符串
NSMutableString *stringM1 = [[NSMutableString alloc] initWithString:@"字符串"];

可用cString打印字符串内容,它返回的是一个char *指针地址。

         NSString *string = @"abdc";NSLog(@"%@, %s", string, [string cString]);//abc, abcNSLog(@"lenght = %i", [string length]);//4

类型限定词

ObjC中的数据类型定义非常有意思,支持组合定义,这些限定词主要包括:long, long long, short, unsigned和signed这几个,它的作用是扩充原有数字的表述范围,具体的范围会根据系统决定,比如

long int factorial; //声明为long的整形变量

long, long long, short, unsigned和signed

类型运算符

  1. 四则运算: +、 -、 *、 \、 %、++、–
  2. -(负号)
  3. 类型强转,这里和java一样, 比如这样的写法 int a = (int)f,f为一float类型
  4. 赋值运算:=、!=、+=、-=、/=、*=
  5. 三元运算符:condition ? expression1: expression2
  6. 位运算:&、 |、 ^、 ~(求反)、 << 、>>
  7. 关系运算:==、!=、< 、 > 、 <= 、 >=

运算规则

主要是数值上面:

  • 同类型的的数相互运算,结果是同类型;
  • bool, char, short, int, bit field, enum全部转为int再运算;
  • 大类型与小类型运算结果为大类型,比如long int / short int = long int;

数据打印

以上类型如果需要用NSLog等函数打印时,其占位符表示都不太一样,大体如下。当用%@时表示可以打印任何内容。看似很复杂,其实就四个特殊的,float, long, unisigned, long long,分别用f, l(L), u(U), ll(LL)来表示,其它的不是太常用

类型实例示例NSLog字符
char‘a’ ‘\n’%c
short int123%hi, %hx, ho
unsigned short int123%hu, %hx, %ho,%hx
int12, -97, 0177(8进制)0xFEE0(16进制)%i, %x, %o
unsigned int12u, 100U, 0xFFU%x, %0, %u
long int12L, -2001, 0xFFFFL%li, %lx, %lo
unsigned long int12UL, 100ul, 0xFFFFUL%lu, %lx, %lo
long long int500ll, 0xe5e5e5LL%llu, %llx, %llo
float12.32f, 3.1e-5f%f, %e, %,g, %a
double12.32, 3.1e-5%f, %e, %g, %a
long double12.34L, 3.1e-5l%Lf, %Le, %Lg
idnil%p
**p(指针)%@
  1. %@:是一个通用字符可表示任何数据,可归类为打印对象,它会调用类的description:方法;
  2. %s:打印字符串

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/294854.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

南洋万邦与实在智能达成战略合作,AI Agent智能体助力上海政企数字化转型

2024年3月29日&#xff0c;浙江实在智能科技有限公司&#xff08;简称“实在智能”&#xff09;与上海南洋万邦软件技术有限公司&#xff08;简称“南洋万邦”&#xff09;签订战略合作协议&#xff0c;双方正式建立战略合作伙伴关系。 在这次战略合作中&#xff0c;南洋万邦和…

基于深度学习的端到端自动驾驶的最新进展:调研综述

基于深度学习的端到端自动驾驶的最新进展&#xff1a;调研综述 附赠自动驾驶学习资料和量产经验&#xff1a;链接 论文链接&#xff1a;https://arxiv.org/pdf/2307.04370.pdf 调研链接&#xff1a;https://github.com/Pranav-chib/ 摘要 本文介绍了基于深度学习的端到端自…

inBuilder 低代码平台新特性推荐 - 第十七期

今天来给大家带来的是 inBuilder 低代码平台特性推荐系列第十七期——如何在列表上添加图片。 一、 场景介绍 在表单开发的业务场景中&#xff0c;会有需要在列表上显示图片的场景&#xff0c;本文以车辆登记信息场景为例&#xff0c;介绍如何在列表上添加图片的开发过程。 …

CTF题型 nodejs(2) Js沙盒vmvm2逃逸原理总结典型例题

CTF题型 nodejs(2) Js沙盒逃逸原理&典型例题 文章目录 CTF题型 nodejs(2) Js沙盒逃逸原理&典型例题一.vm原理以及逃逸1.基本用法2.如何逃逸汇总1)this为对象2)this为null( Object.create(null))a .可用输出直接触发toString方法b.调用属性触发 3)Object.create(null)沙…

QT 如何集成minizip和zlib, 实现多文件压缩?

一.zlib库的源码地址 官网地址:zlib Home Site,找到"All released versions of zlib",点击选择自己的版本,这里我用的是zlib-1.2.11版本,下载源码。 二.mac下编译,window下cmake正常编译即可。 1.我这里需要使用的是64位的。 所以,cmake源码里添加如下代码。 …

论文精读--GPT4

现有的所有模型都无法做到在线学习&#xff0c;能力有限&#xff0c;而让大模型拥有一个tools工具库&#xff0c;则可以使大模型变成一个交互式的工具去协调调用API完成任务&#xff0c;同时GPT4还联网了&#xff0c;可以不断地更新自己的知识库 多模态模型&#xff0c;接受文…

关于 C/C++ 1Z(17)开源项目 openppp2 协同程式切换工作流

下述为开源项目 openppp2&#xff08;github&#xff09;构建工作在 C/C 17 的 stackful 有栈协同程式的工作流切换示意图&#xff1a; 在 openppp2 之中采用人工手动方式管理协同程式之间的切换&#xff0c;每个中断过程只是保存线程栈信息&#xff08;如寄存器、当前#PC EIP&…

GeoLite2 geoip数据库下载和使用

GeoLite2 数据库是免费的 IP 地理定位数据库&#xff0c;与MaxMind 的 GeoIP2 数据库相当&#xff0c;但准确度较低 。GeoLite2 国家、城市和 ASN 数据库 每周更新两次&#xff0c;即每周二和周五。GeoLite2 数据还可作为 GeoLite2 Country 和 GeoLite2 City Web 服务中的 Web …

新手学python还是c?

考虑到个人情况和职业规划是非常重要的。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 Python作为初学者入门语言…

怎么更新sd-webui AUTOMATIC1111/stable-diffusion-webui ?

整个工程依靠脚本起来的&#xff1a; 可直接到stable-diffusion-webui子目录执行&#xff1a; git pull更新代码完毕后&#xff0c;删除venv的虚拟环境。 然后再次执行webui.sh&#xff0c;这样会自动重新启动stable-diffusion-webui.

“超越摩尔定律”,存内计算走在爆发的边缘

前言 过去几十年来&#xff0c;在摩尔定律的推动下&#xff0c;处理器的性能有了显著提高。然而&#xff0c;传统的计算架构将数据的处理和存储分离开来&#xff0c;随着以数据为中心的计算&#xff08;如机器学习&#xff09;的发展&#xff0c;在这两个物理分离的单元之间传…

HarmonyOS 应用开发之LifecycleForm接口切换LifecycleApp接口切换 LifecycleApp接口切换

LifecycleForm接口切换 FA模型接口Stage模型接口对应d.ts文件Stage模型对应接口onCreate?(want: Want): formBindingData.FormBindingData;ohos.app.form.FormExtensionAbility.d.tsonAddForm(want: Want): formBindingData.FormBindingData;onCastToNormal?(formId: string…

百度网站收录提交入口

百度网站收录提交入口 在网站刚建立或者更新内容后&#xff0c;及时将网站提交给搜索引擎是提高网站曝光和获取流量的重要步骤之一。百度作为中国最大的搜索引擎之一&#xff0c;网站在百度中的收录情况尤为重要。下面介绍一下如何通过百度的网站收录提交入口提交网站。 1. 百…

Pygame基础9-射击

简介 玩家用鼠标控制飞机&#xff08;白色方块&#xff09;移动&#xff0c;按下鼠标后&#xff0c;玩家所在位置出现子弹&#xff0c;子弹匀速向右飞行。 代码 没有什么新的东西&#xff0c;使用两个精灵类表示玩家和子弹。 有一个细节需要注意&#xff0c;当子弹飞出屏幕…

视觉里程计之对极几何

视觉里程计之对极几何 前言 上一个章节介绍了视觉里程计关于特征点的一些内容&#xff0c;相信大家对视觉里程计关于特征的描述已经有了一定的认识。本章节给大家介绍视觉里程计另外一个概念&#xff0c;对极几何。 对极几何 对极几何是立体视觉中的几何关系&#xff0c;描…

从学习海底捞到学习巴奴,中国餐饮带洋快餐重归“产品主义”

俗话说“民以食为天”&#xff0c;吃饭一向是国人的头等大事&#xff0c;餐饮业也是经济的强劲助推力。新世纪以来&#xff0c;餐饮业不断讲述着热辣滚烫的商业故事。 2006年&#xff0c;拥有“必胜客”、“肯德基”等品牌的餐饮巨头百胜集团&#xff0c;组织两百多名区域经理…

Effective-C++阅读解析条款(条款二:尽量以const,enum,inline替换#define)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 书中说这个条款或许改为“宁可以编译器替换预处理器”比较好&#xff0c;这句话在我看来原因是这样的&#xff1a; 如果我们有这样一个宏(假设写这个宏的人比较粗心)&#xff1a;#define Add(x, y) x y 我们本意是想得到…

全栈的自我修养 ———— redux入门(看这么一篇就够了!!!)

redux时react中负责状态管理的工具 一、下载二、配置1、目录2、store配置3、redux中index.js配置4、启动类中index.js配置 三、使用1、调用store的数据2、调用store里面的方法3、改变store里面的值 一、下载 npm I reduxjs/toolkit react-redux二、配置 1、目录 modules里面…

uniapp-打包IOS的APP流程

打包前所需配置 在manifest文件内配置 1. APP图标 2. 启动界面 有三种启动界面配置 第一种是 HBuilderX 官方给的通用启动界面&#xff0c;页面单一&#xff0c;屏幕中间就一个圆框图标 第二种是自定义的启动图&#xff0c;无法通过AppStore的审核 第三种是自定义storyboard启动…

ios应用内支付

用uniapp开发iOS应用内支付 准备前端代码服务器端处理如果iOS支付遇到问题实在解决不了&#xff0c;可以联系我帮忙解决&#xff0c;前端后端都可以解决&#xff08;添加的时候一定要备注咨询iOS支付问题&#xff09; 准备前端代码 获取支付通道 (uni.getProvider) uni.getPr…