ObjectiveC-05-复杂和特殊数据类型

这一节中会详细介绍下ObjectiveC中的复杂数据类型,这些类型不太是太归类。但非常有用,有的用于定义变量、有的则是专门用于方法的返回值。

常用的大概有如下这些:
在这里插入图片描述
以上这些特殊的数据类型都可用于变量、方法返回值、方法参数使用,但是不同种类还是有些倾向的用法。

复杂数据类型

数组

数组同其它语言基本一样,也是通过下标等读写,不同的就是定义时如果是个复杂对象则用*定义,字符串数组只能用,数组的语言格式为:

Type name[length] = {};
Type *name[length] = {};

在ObjeC中还有一个名为NSArray的也称为数组的对象,它和本节所讨论的数组有些区别:

  1. 数组的大小是不可变的,即一旦实例化后,其length不能动态改变,而NSArray则可以;
  2. NSArray中的元素只能是对象,不能是基本数据类型,如果制定集合类的基本元素集合只能用数组;

数组初始化

一般建议要指定一个大小,也可以不指定。如果不指定的话系统会按照当前实例化后的元素个数自动设置。

//Fraction为自定义的一个类
Fraction *fra[100];

//不指定大小,默认为值的长度;也可以指定大小,多余的全部采用默认值
int a[] = {1,2,4};
int a[12] = {1,2,4};


//  \0是一个特殊标识,如果字符数组以这种方式结尾,则可以通过NSLog(@"\s", letters)方式打印,否则只能遍历打印
char letters[5] = {'a', 'b', 'c'}
char letters[5] = {'a', 'b', 'c', '\0'}

数组的遍历

        int a[3] = {1,2,4};
        NSLog(@"%i", a[0]);
        for(int i=0; i<3; i++){
            NSLog(@"%i", a[i]);
        }

多维数组

int a[4][5] = { //4行5列
    {1,2,3,4,5}
    .....
}

字符串数组

        NSString *strs[2] ={@"a", @"b"};
        for(int i=0; i<3; i++){
            NSLog(@"%@", strs[i]);
        }

在ObjC中建议用NSArray来充当数组功能,它允许大小可变,而数组的大小不可变,因为数组的大小是透明不可变的,所以在ObjC中并没有提供获取数组大小的类似的函数;

枚举

枚举就是把一系列的值指给一个变量,在OjbC中用关键字enum开头,另外需要注意的是在ObjectiveC中也有一个名为NSEnumerator的枚举对象,这两个一个是简单关键字,另一个是对象类,但在使用上区别不大,NSEnumerator会在Function框架时再详细说明,声明enum枚举变量的语法格式如下:

基本语法

enum enumName {enumValue1, ..., enumValueN};

//---示例
enum flag {true, false}; //声明一个枚举类型,true默认值为0, false为1,依次顺延
enum flag  startFlag, endFlag; //声明两个flag类型的变量startFlag和endFlag
startFlag = true;
endFlag = false;

指定枚举值

//up=0, down=1, left=10, right=11
enum direction {up, down, left=10, right};

下面是一些特殊的设置

//指定数据类型,unsigned short int 标识主要是为了类型检查
enum iphoneModels : unsigned short int { iphone2, iphone3};

//定义一个名为amouth的枚举类型,包含两个可选值
enum {january=1, february} amonth;

综合示例-在switch中的用法

        enum month {january=1, february, march, ...., december};
        enum month amonth; //声明了此枚举类型的一个变量
        int days;
        
        //从屏幕接收输入值
        scanf("%i", &amonth);
        switch(amonth){
            case january:
                days = 31;
                break;
            case march:
            case november:
                days=30;
                break;
            default:
                days = 0;
                break;
        }
        
        NSLog(@" days = %i", days); //输入1,输出days=31

综合示例2-定义复杂的结构体

下面这个例子,做为初学者看起来可能会有点蒙属于正常情况,因为像typedef, struct这些语法还都没有讲,此处也不会详细讲解这些内容,先简单描述一下。可学习完后续课程再回顾下这个例子:

  • typedef:重命名,比如typedef a b;意思就是把a 重新命名为b,这样源码中会自动把a替换为b;
  • struct:其实这是C语言的用法,在ObjC中也适用,它是把一组不可再分的属性统一起一个名字,这样结构可能更清晰。
#import <Foundation/Foundation.h>

//定义三种图形,每个带一个默认编号,比如circle=0,依次类推
typedef enum{
    circle,
    rectangle,
    egg
}ShapeType;

// 定义图形的颜色
typedef enum{
    red,
    green,
    yellow
}ShapeColor;

//定义图形的坐标和尺寸
typedef struct{
    int x, y, width, height;
} ShapeRect;

//组合一个图形的描述:类型+颜色+坐标尺寸
typedef struct{
    ShapeType type;
    ShapeColor color;
    ShapeRect bounds;
}Shape;


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!\n");
        
        Shape shapes[3];
        ShapeRect rect_0 = { 0, 0, 30, 30 };
        shapes[0].type = circle;
        shapes[0].color = red;
        shapes[0].bounds = rect_0;
    }
    return 0;
}

id和动态类型绑定

id是一种通用的数据类型,它可以存储任何对象,也称为动态类型,内容为指向其数据结构的指针。它相当于java中的浮型的概念,比如 id graphicObject,graphicObject可以存储任意数据类型,id是多态和动态类型的基础,可以简单理解为id是一个指针,它可以指向任何对象。其主要特点就是运行时检查,加快了程序编译的速度也带来了运行时的风险。

//做为变量声明
id item;

//做为方法返回值和参数
- (id) register: (id) sender;

注意事项:

  • id 不能使用.运算符,必须用[]的方式调用;
  • 加快了程序编译的速度也带来了运行时的风险;

更多示例

id shape = [[Shape alloc] init]];//这里的Shape是一个自定义的类;
[shape draws]
id dataValue;  //这里没有*号
Fraction *f1 = [[Fraction alloc] init];
Complex *c1 = [[Complex alloc] init];

dataValue = f1;
[dataValue showPage];

dataValue = c1;
[dataValue print];

instancetype

一般用于类的初始化函数的返回值,它表示从方法返回的数据类型与它的初始化类相同。是一种编译器辅助标识,比如NSString类的实现就是如下定义的,如下:

+ (instancetype)string;
+ (instancetype)stringWithString:(NSString *)string;

- (nullable instancetype)initWithUTF8String:(const char *)nullTerminatedCString;

在使用时,一般把可能会被覆盖的初始化函数用此标识来定义,这样可以保证初始化后的类实例的类似不会出现问题。比如下面就是一个比较好的设计模式,把真正实例化的代码放在此标识的函数中:

在这里插入图片描述
示例代码如下:

- (id) init1(){
    [self initFinally: 0 age: 0];//委托给initFinally来实现
}

- (id) init2:(int) sex{
    [self initFinally: sex age: 0];//委托给initFinally来实现
}

- (instancetype) initFinally:(int) sex age(int) age{
    self.sex = sex;
    self.age = age;
    //设置真正的初始化代码;
}

特殊数据类型

Class

类对象的引用,指向其数据结构的指针,示例如下:

@interface Fraction : NSObject
@end

NSLog(@"%@", [Fraction class]); //~~Fraction

SEL

选标,编译器分配用来区分方法名的编码,其实就是方法的定义(方法名+参数),一般用于方法回调使用,在Function框架中会详细介绍其用法,下面给出一个简单的示例:

SEL action =  @selector(setTo:over:); //为setTo方法生成一个SEL
Boolean boolean = [Fraction instanceMethodForSelector: action]; //验证类是否响应了setTo方法

id obj;
[obj performSelector: setTo:over:] //调用setTo:over:方法

IMP

函数指针,指向实现方法的指针,返回id;简单来说就是Objective-C 在运行时寻找匹配消息的IMP(implementation),给一个方法起个名字,实现动态调用,不用再使用[对象 message]的方式。

#import <Foundation/Foundation.h>
#import <objc/runtime.h> //一定要引入


@interface MyClass : NSObject
- (void)myMethod;
@end

@implementation MyClass
- (void)myMethod {
    NSLog(@"myMethod called");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc] init];
        Method method = class_getInstanceMethod([MyClass class], @selector(myMethod));
        IMP imp = method_getImplementation(method);
        
        //转为指针
        void (*func)(id, SEL) = (void *)imp;
        
        // 调用MyClass.Mythod(),输出 myMethod called
        func(obj, @selector(myMethod));
    }
    return 0;
}

空值的表示

nil

空的对象指针,返回(id)0。用来表示一个对象是空对象,即想要表示此对象不存在。给对象赋值时一般会使用object = nil,表示我想把这个对象释放掉;或者对象引用计数器为0了,系统将这块内存释放掉,这个时候这个对象被置为nil。

		//nil是void*类型,可看作id类型的对象
        NSLog(@"nil指向的对象:%d,nil自身的地址:%p",nil,nil);

		//~~nil指向的对象:0,nil自身的地址:0x0

Nil

空的类指针,返回(Class)0,是用来表示一个类是空类。比如:Class myClass = Nil;。和nil没有明确的区分,也就是说凡是使用nil的地方都可以用Nil来代替,反之亦然。约定俗成地将nil表示一个空对象,Nil表示一个空类。

        //NiL是void*类型,在OC中可看作id类型的对象(OC对象就是一个指针)
        NSLog(@"NiL指向的对象:%d,Nil自身的地址:%p", Nil,Nil);
		
		//~~NiL指向的对象:0,Nil自身的地址:0x0

NULL

空值,字面量,返回(void *) 0。NULL是在C/C++中的空指针,在C语言中,NULL是无类型的,只是一个宏,它代表空。C语言中,当我们使用完一个指针以后,通常会设置其指向NULL。如果没有设置,这个指针就成了所谓的野指针,然后其它地方不小心访问了这个指针是很容易造成非法访问的,常见的表现就是崩溃了。

既然Objective-C是基于C语言的面向对象语言,那么也会使用到C语言类型的指针,比如使用const char *类型,判断是否为空时,是使用p != NULL来判断的。

        //NULL是void*类型,若在OC中可看作id类型的对象(OC对象就是一个指针)
        NSLog(@"NULL指向的对象:%d,NULL自身的地址:%p",NULL,NULL);
        
        //~~NULL指向的对象:0,NULL自身的地址:0x0

总结如下:

标识含义
NULL(void *)0C 指针的字面空值
nil(id)0Objective-C 对象的字面空值
Nil(Class)0Objective-C 类的字面空值

NaN

NaN,是Not a Number的缩写。NaN 用于处理计算中出现的错误情况,这个方法其实是C语言的方法,用的不是太多。

        float a = sqrt(2);
        NSLog(@"is a number :%@",  isnan(a));

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

目标伪类选择器

E:target选择匹配E的所哟元素&#xff0c;且匹配元素被相关url指向 鼠标点击右边京东秒杀跳转到京东秒杀div&#xff0c;并变成黄色 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&…

HTML块级元素和内联元素(头部和布局)

目录 1.HTML块级和内联标签&#xff1a; 1.块级元素&#xff1a; 2.内联元素: 3.元素嵌套&#xff1a; 4.元素转换&#xff1a; 示例如下: 2.内联框架&#xff1a; 前言&#xff1a; 示例如下: 3.布局&#xff1a; 4.头部标签&#xff1a; 前言&#xff1a; 说明&…

Java获取当前时间

获取当前的时间 在Java中获取时间和日期使用Date类中的 toString方法 import java.util.Date;public class DateDemo {public static void main(String[] args) {Date date1new Date();System.out.println(date1.toString());} } 进一步格式化时间 SimpleDateFormat 是格式化…

Netty组件优化之FastThreadLocal

ThreadLocal:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132995427 Netty中的FastThreadLocal是对Java中的FastThreadLocal的优化主要是为了解决ThreadLocal中线性查找 带来的性能下降同时实现快速查找和赋值 FastThreadLocal构建这里的index代表一个编号&#xff0c;从…

ROS机器人入门第五课:话题通信自定义msg

文章目录 ROS机器人入门第五课&#xff1a;话题通信自定义msg一、介绍二、流程&#xff08;一&#xff09;定义msg文件&#xff08;二&#xff09;编辑配置文件&#xff08;三&#xff09;编译 三、话题通信自定义msg调用&#xff08;一&#xff09;调用流程0.vscode配置1.发布…

论文笔记 - :MonoLSS: Learnable Sample Selection For Monocular 3D Detection

论文笔记✍MonoLSS: Learnable Sample Selection For Monocular 3D Detection &#x1f4dc; Abstract &#x1f528; 主流做法限制 &#xff1a; 以前的工作以启发式的方式使用特征来学习 3D 属性&#xff0c;没有考虑到不适当的特征可能会产生不利影响。 &#x1f528; 本…

基于java+SpringBoot+Vue的网上书城管理系统设计与实现

基于javaSpringBootVue的网上书城管理系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 网上书城管理系统是一个基于互联网的在线购书平台&#…

基于springboot实现旅游网站系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现旅游网站系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;旅游网站当然也不能排除在外&#xff0c;随着旅游网站的不断成熟&#xff0c;它彻底改变了过去传统的旅游…

CI/CD实战-jenkins结合ansible 7

配置主机环境 在jenkins上断开并删除docker1节点 重新给master添加构建任务 将server3&#xff0c;server4作为测试主机&#xff0c;停掉其上后面的docker 在server2&#xff08;jenkins&#xff09;主机上安装ansible 设置jenkins用户到目标主机的免密 给测试主机创建用户并…

windows操作系统本地部署开源语言模型ChatGLM3-6b,超详细

前言 首先感谢智谱AI和清华大学 KEG 实验室联合开源的ChatGLM3对话预训练模型&#xff0c;让我们国人有属于自己的AI聊天机器人。 ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用了更多样的训练数据、更充分的训练步数和更合理的训练策略。在语义、数学、推理、代码、知识等不…

mysql 用户管理-权限管理

学习了用户管理&#xff0c;再学习下权限管理。 3&#xff0c;权限管理 权限管理主要是对登录到MySQL的用户进行权限验证。所有用户的权限都存储在MySQL的权限表中&#xff0c;不合理的权限规划会给MySQL服务器带来安全隐患。数据库管理员要对所有用户的权限进行合理规…

C++练级之路——C++入门

1、命名空间 在C/C中会出现大量的变量&#xff0c;函数&#xff0c;起名字是一个很大的问题&#xff0c;为了防止命名重复&#xff0c;就出现了命名空间的概念&#xff0c;使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突和名字污染 #include <st…

黄金涨是商品牛市的领先信号

自2022年11月以来&#xff0c;黄金价格持续上涨&#xff0c;目前已经突破历史新高&#xff0c;历史上黄金上涨&#xff0c;大多是商品全面牛市的领先信号。在2008年Q4、2019年也出现过&#xff0c;黄金比其他商品更强&#xff0c;但随后的2009年和2020年均是商品的全面牛市。同…

AI副业拆解:使用Suno生成你的专属歌曲

大家好我是在看&#xff0c;记录普通人学习探索AI之路。 今天和大家拆解Suno的定制个性化音乐&#xff0c;Suno应用程序热度非凡&#xff0c;其独特之处在于&#xff0c;用户仅需提供歌词内容与期望的歌曲风格&#xff0c;即可一键生成专属曲目。 Suno的诞生&#xff0c;无疑…

考研数学|零基础张宇全年复习规划+资料分享

可以全程张宇老师的高等数学&#xff0c;张宇老师的拿手绝活是 但是其他科目&#xff0c;还有更好的选择&#xff0c;比如线性代数&#xff0c;汤家凤老师还有李永乐老师讲的都不错&#xff0c;概率论&#xff0c;余丙森老师还有方浩老师讲的很好。下面我就讲清楚&#xff0c;…

FPGA时序优化之Reduce MUXF Mapping

我们都知道&#xff0c;FPGA中的拥塞有&#xff1a;全局拥塞&#xff0c;短线拥塞和长线拥塞。 今天我们就来看短线拥塞的一种解决方案&#xff1a;Reduce MUXF Mapping。 UltraScale的CLB资源 在介绍Reduce MUXF Mapping&#xff0c;我们需要知道什么是MUXF&#xff0c;这就…

MongoDB Atlas维护指南:常见类型、注意事项与窗口设置

为了给Atlas用户更好的产品体验&#xff0c;MongoDB产品团队会进行定期维护。 本文将会介绍&#xff1a; 常见维护项目种类及频率&#xff0c;注意事项维护期间的影响及建议维护窗口设置说明维护告警设置和邮件通知范例 维护窗口常见项目 定期SSL证书轮换软件升级&#xff…

内网渗透-(黄金票据和白银票据)详解(一)

目录 一、Kerberos协议 二、下面我们来具体分析Kerberos认证流程的每个步骤&#xff1a; 1、KRB_AS-REQ请求包分析 PA-ENC-TIMESTAMP PA_PAC_REQUEST 2、 KRB_AS_REP回复包分析&#xff1a; TGT认购权证 Logon Session Key ticket 3、然后继续来讲相关的TGS的认证过程…

基于springboot+vue+Mysql的篮球论坛系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【最全详细解读】Sora都有哪些不足与缺陷?

Sora介绍 Sora是一个能以文本描述生成视频的人工智能模型&#xff0c;由美国人工智能研究机构OpenAI开发。 Sora这一名称源于日文“空”&#xff08;そら sora&#xff09;&#xff0c;即天空之意&#xff0c;以示其无限的创造潜力。其背后的技术是在OpenAI的文本到图像生成模…