OC基础--数据类型与表达式
前言
做iOS开发有3年了,从当初的小白到现在,断断续续看过很多资料,之前也写过一些博文来记录,但是感觉知识点都比较凌乱。所以最近准备抽时间把iOS开发的相关知识进行一个梳理,主要分为OC基础、UI控件、多线程、动画、网络、数据持久化、自动布局、第三方框架等几个模块进行梳理。本系列的所有博文集合参见:iOS开发知识梳理博文集。本文主要介绍 OC基础--数据类型与表达式。
一 数据类型
Objective-C是在C语言基础上拓展出的新语言,所以它是完全兼容C语言代码的,C语言中的基本数据类型如int、float、double和char在Objective-C中是完全可以正常使用的。除此之外,Objective-C还拓展了一些新的数据类型如BOOL、id、instancetype等。
1.1 基本数据类型
因为Objective-C是在C语言基础上拓展出的新语言,所以它是完全兼容C语言代码的,C语言中的基本数据类型都可以正常使用,直接来自C语言中的数据类型如下所示。当然,这些数据类型我们在实际开发过程中很少用到(枚举类型有时候会用到)。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
char ch = 'a'; //字符型
short sh = ; //短整型
int i8 = ; //整型 八进制
int i10 = ; //整型 十进制
int i16 = 0x15; //整型 十六进制
//输出结果: i8 = 13, i10 = 15 i16 = 21
NSLog(@"i8 = %d, i10 = %d i16 = %d", i8, i10, i16);
long l = 6l; //长整型
float f = 3.4f; //单精度浮点型
double d = 5.6; //双精度浮点型//枚举类型
enum EnumDemo {
Spring, //默认为0,后面依次自增
Summer,
Autumn = , //可以指定整数,后面的在这个基础上自增
Winter
};
//结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员
//结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙)
struct StructDemo {
NSString *name;
int length;
};
//共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,共用体的所有成员占用同一段内存,同一时刻只能保存一个成员的值,修改一个成员会影响其余所有成员。
union UnionDemo {
int n;
char ch;
double f;
};
}
return ;
}
1.1.1 不同数据类型的占用存储空间
不同的数据类型占用的存储空间不同,同一数据类型在不同编译器环境下占用的存储空间也不一样。各数据类型占用的存储空间如下表所示。
| 数据类型 | 16位编译器 | 32位编译器 | 64位编译器 |
|---|---|---|---|
| char | 1byte | 1byte | 1byte |
| int | 2byte | 4byte | 4byte |
| float | 4byte | 4byte | 4byte |
| double | 8byte | 8byte | 8byte |
| short int | 2byte | 2byte | 2byte |
| unsigned int | 2byte | 4byte | 4byte |
| long | 4byte | 4byte | 8byte |
| unsigned long | 4byte | 4byte | 8byte |
| long long | 8byte | 8byte | 8byte |
1.1.2 不同数据类型的输出格式
不同数据类型在打印时,我们需要按照指定的格式进行输出,在OC中NSLog输出格式如下表所示。
| 格式字符 | 说明 | 格式字符 | 说明 |
|
d |
带符号十进制 | f | 小数形式输出,默认输出6位小数 |
| o | 无符号八进制 | e | 指数形式输出,数值不分默认输出6位小数 |
| x | 无符号十六进制 | g | 自动选用%f或%e输出,保证以最简形式输出,并不会输出无意义的0 |
| u | 无符号十进制 | p | 以十六尽职形式输出指针变量所代表的地址值 |
| s | 输出C风格字符串 | l | 用在d、o、x、u之前用于输出长整型;在f、e、g之前用于输出长浮点型 |
| m | 用于制定输出数据所占的最小宽度为m位 | .n | 对于浮点数,表示输出n位小数,对于字符串,表示截取的字符个数 |
| _ | 表述输出的数值向左边对齐 |
1.2 OC封装的数据类型
除了上面的基本数据类型之外,Objective-C还拓展了一些新的数据类型如BOOL、NSInteger、NSString、CGFloat、id、instancetype等。此外,还有NSNumber、NSValue、NSData等封装类型,有NSDictionary、NSArray、NSSet等集合数据类型,有CGRect/NSRect、CGPoint/NSPoint、CGSize/NSSize等尺寸相关的 ,还有NSRange、NSIndex等范围相关。
1.2.1 BOOL/Boolean
Objective-C中的BOOL类型在不同的架构系统上是不一样的,所以在64-bit架构系统下BOOL是对应C语言中的bool,值只能是1(YES)和0(NO),32-bit架构下是无符号字符型。下面是OC中对BOOL的定义 :
#if defined(__OBJC_BOOL_IS_BOOL)
// Honor __OBJC_BOOL_IS_BOOL when available.
# if __OBJC_BOOL_IS_BOOL
# define OBJC_BOOL_IS_BOOL
# else
# define OBJC_BOOL_IS_BOOL
# endif
#else
// __OBJC_BOOL_IS_BOOL not set.
# if TARGET_OS_OSX || TARGET_OS_MACCATALYST || ((TARGET_OS_IOS || ) && !__LP64__ && !__ARM_ARCH_7K)
//非64-bit架构或非__ARM_ARCH_7K
# define OBJC_BOOL_IS_BOOL
# else
//64-bit架构并且__ARM_ARCH_7K
# define OBJC_BOOL_IS_BOOL
# endif
#endif //所以在64-bit架构系统下BOOL是对应C语言中的bool,否则是无符号字符型
#if OBJC_BOOL_IS_BOOL
typedef bool BOOL;
#else
# define OBJC_BOOL_IS_CHAR
typedef signed char BOOL;
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
// even if -funsigned-char is used.
#endif #define OBJC_BOOL_DEFINED #if __has_feature(objc_bool)
#define YES __objc_yes
#define NO __objc_no
#else
#define YES ((BOOL)1)
#define NO ((BOOL)0)
#endif
//用iPhone5和iPhone8模拟器做个实验 BOOL isOK = ;
NSLog(@"%d", isOK); // iPhone5的打印结果 23
// iPhone8的打印结果 1
Objective-C中的Boolean类型其实就是一个无符号字符型。
/********************************************************************************
Boolean types and values
Boolean Mac OS historic type, sizeof(Boolean)==1
bool Defined in stdbool.h, ISO C/C++ standard type
false Now defined in stdbool.h
true Now defined in stdbool.h
*********************************************************************************/
typedef unsigned char Boolean;
1.2.2 NSInteger
OC中的NSInteger就是对整型的一个封装,64-bit系统上NSInteger对应的是长整形,32-bit系统上对应的是整型。具体我们可以看OC中的源码的定义:
//64-bit系统上NSInteger对应的是长整形,32-bit系统上对应的是整型
#if __LP64__ || 0 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
1.2.3 数值封装类型 NSNumber、NSValue、NSData
我们在编码中,很多时候需要将C里面原生的数据 (通常是一些结构体) 封装成对象,这样可以用NSDictionary或者NSArray来存取访问。尤其是一些做适配的情况下,这种封装是不可避免的。Objective-C提供了不少类可以帮助我们,比较常见的是NSNumber,NSValue和NSData。
NSValue主要就是将这些原生的数据封装成对象,方便我们进行存储访问。NSValue主要用来封装自定义的数据结构,可以是系统框架提供的CGRect/CGPoint/CGSize等数据结构,也可以是自己定义的struct。
//封装
+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type; //解封
- (void)getValue:(void *)value;
//此外还提供了对基本的尺寸范围相关的封装和解封
+ (NSValue *)valueWithPoint:(NSPoint)point;
+ (NSValue *)valueWithSize:(NSSize)size;
+ (NSValue *)valueWithRect:(NSRect)rect;
+ (NSValue *)valueWithEdgeInsets:(NSEdgeInsets)insets API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); @property (readonly) NSPoint pointValue;
@property (readonly) NSSize sizeValue;
@property (readonly) NSRect rectValue;
@property (readonly) NSEdgeInsets edgeInsetsValue API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
使用NSValue对NSPoint进行封装、解封的示例代码如下。
NSPoint point = NSPointFromCGPoint(CGPointMake(, ));
// NSDictionary *dic = @{@"point" : point}; //报错,字典中必须是对象 //通过转化为NSValue进行保存
NSValue *value = [NSValue valueWithPoint:point];
NSDictionary *dic = @{@"point" : value};
//从字典中获取NSValue,并从该对象中获取对应的NSPoint值
NSValue *vv = dic[@"point"];
NSPoint pp = [vv pointValue];
NSLog(@"%@", NSStringFromPoint(pp));
使用NSValue对自定义结构体进行封装和解封的示例代码如下。
//结构体定义
typedef struct StructDemo {
NSString *name;
int age;
} StructDemoTag; //数据创建
StructDemoTag stDemo = {@"zhangsan", }; //封装
NSValue *vv2 = [NSValue value:&stDemo withObjCType:@encode(StructDemoTag)]; NSDictionary *dic2 = @{@"struct_demo" : vv2}; //解封
NSValue *vv3 = dic2[@"struct_demo"];
StructDemoTag stDemo2 = {};
[vv3 getValue:&stDemo2]; NSLog(@"name: %@, age: %d", stDemo2.name, stDemo2.age);
//name: zhangsan, age: 12
NSNumber继承自NSValue,主要是用来封装ANSI C内置的数据,比如char,float,int等等。这个类提供了一些封装/解封的方法,这个使用方法很简单,就不展示了。
//封装方法
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; //解封方法
- (char)charValue;
- (unsigned char)unsignedCharValue;
- (short)shortValue;
- (unsigned short)unsignedShortValue;
- (int)intValue;
- (unsigned int)unsignedIntValue;
- (long)longValue;
- (unsigned long)unsignedLongValue;
NSData主要是提供一块原始数据的封装,将一些图片、文件、字符串等数据转化为字节流数据,方便数据的封装和流动,比较常见的是NSString/NSImage以及文件数据的封装与传递。在应用中,最常用于访问存储在文件中或者网络资源中的数据。一般解封方法在图片UIImage、字符串NSString中有对应的从NSData数据创建。
//以下类方法全部都有成员方法的实现和接口,这里不一一展示 //直接从data封装
+ (instancetype)dataWithData:(NSData *)data; //指定长度的封装
+ (instancetype)dataWithBytes:(nullable const void *)bytes length:(NSUInteger)length; //封装文件对应的
+ (nullable instancetype)dataWithContentsOfFile:(NSString *)path;
+ (nullable instancetype)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr; //封装url对应的
+ (nullable instancetype)dataWithContentsOfURL:(NSURL *)url;
+ (nullable instancetype)dataWithContentsOfURL:(NSURL *)url options:(NSDataReadingOptions)readOptionsMask error:(NSError **)errorPtr;
NSData在字符串中的使用示例代码如下:
NSString *str = @"hello object-c";
//封装
NSData *data = [NSData dataWithBytes:[str UTF8String] length:str.length];
//解封
NSString *str2 = [NSString stringWithUTF8String:[data bytes]];
NSLog(@"str:%@", str2);
1.2.4 字符串NSString/NSMutableString
字符串内容比较多,我们后面单独写一篇,到时候链接补上来。
1.2.5 集合数据类型
OC中的集合框架主要就是数组(NSArray / NSMutableArray、字典(NSDictionry / NSMutableDictionry)、集合(NSSet / NSMutableSet)。这一部分内容也比较多,我们后面也会单独补充一篇,到时候链接补上来。
1.2.6 尺寸、范围相关的类型
Object-C中有CGRect/NSRect、CGPoint/NSPoint、CGSize/NSSize等尺寸相关的,其实CG开头的和NS开头的都是一个东西,都是struct定义的尺寸相关的结构体,只是定义在不同的框架中。
/* Points. */
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CG_BOXABLE CGPoint CGPoint; //NSPoint就是CGPoint
typedef CGPoint NSPoint; /* Sizes. */ struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CG_BOXABLE CGSize CGSize; //NSSize就是CGSize
typedef CGSize NSSize; /* Rectangles. */
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CG_BOXABLE CGRect CGRect; //NSRect就是CGRect
typedef CGRect NSRect;
CGRect rect = CGRectMake(, , , );
NSRect rect2 = NSRectFromCGRect(rect); CGPoint point = CGPointMake(, );
NSPoint point2 = NSPointFromCGPoint(point); CGSize size = CGSizeMake(, );
NSSize size2 = NSSizeFromCGSize(size); NSRange range = NSMakeRange(, );
各种尺寸相关的结构体类型数据在OC中打印该如何打印呢?我们需要将结构体类型转为字符串进行打印,系统提供了相应的方法。示例代码如下。
CGRect rect = CGRectMake(, , , );
NSRect rect2 = NSRectFromCGRect(rect);
NSLog(@"%@", NSStringFromRect(rect)); CGPoint point = CGPointMake(, );
NSPoint point2 = NSPointFromCGPoint(point);
NSLog(@"%@", NSStringFromPoint(point)); CGSize size = CGSizeMake(, );
NSSize size2 = NSSizeFromCGSize(size);
NSLog(@"%@", NSStringFromSize(size)); NSRange range = NSMakeRange(, );
NSLog(@"%@", NSStringFromRange(range));
OC基础--数据类型与表达式的更多相关文章
- JavaScript的基础数据类型和表达式
Java Script的基础数据类型和表达式 基本的数据类型: number(数值)类型:可分为整数和浮点数 string(字符)类型:是用单引号“'”或者双引号“"”来说明的. boole ...
- OC基础数据类型-NSNumber
1.NSNumber:专门用来装基础类型的对象,把整型.单精度.双精度.字符型等基础类型存储为对象 //基本数据类型 //专门用来装基础类型的对象 NSNumber * intNumber = [[N ...
- OC基础数据类型-NSString
1.字符串的初始化 //字符串的初始化 NSString *str = @"Hello world!"; NSString *str2 = [[NSString alloc] in ...
- OC基础数据类型-NSData-NSMutableData-NSString
NSData和NSMutableData存储的是二进制数据,在文件操作,网络,以及核心图形图像中使用较广泛.NSData创建后不可以再修改,NSMutableData可以再次修改. 1.NSStrin ...
- OC基础数据类型-NSSet
1.集合:集合(NSSet)和数组(NSArray)有相似之处,都是存储不同的对象的地址:不过NSArray是有序的集合,NSSet是无序的集合.集合是一种哈希表,运用散列算法,查找集合中的元素比数组 ...
- OC基础数据类型-NSData
1.NSData,数据,当我们需要把一些信息写入到文件里或发送到网络上,我们需要把这些数据转换下,变成纯粹的0.1字符流 1 NSString * str = @"hello, world! ...
- 【转】 OC基础数据类型-NSSet
原文 : http://www.cnblogs.com/GISerYang/p/3340937.html 1.集合:集合(NSSet)和数组(NSArray)有相似之处,都是存储不同的对象的地址:不过 ...
- OC基础数据类型-NSValue
1.NSValue:将指针等复杂的类型存储为对象 struct sct { int a; int b; }sctt; NSValue * value = [[NSValue alloc] initWi ...
- OC基础数据类型-NSDictionary
1.字典NSDictionary 字典与数组的区别:数组讲究顺序,而字典可以快速帮助我们找到数据,数据是我们的目的,键是我们的手段 NSDictionary *dict = [[NSDictionar ...
随机推荐
- springboot 使用mybatis-generator自动生成代码
这里只介绍mybatis generator生成代码 一.pom配置 在build-->plugins-->添加plugin <plugin> <groupId>o ...
- 云计算&存储测试:FIO工具入门与实战
一.关于FIO 1.1 简介 FIO是一个开源的I/O压力测试工具,主要是用来测试磁盘的IO性能,也可测试cpu,nic的IO性能.它可以支持13种不同的I/O引擎,包括:sync,mmap, lib ...
- [Err] 126 - Incorrect key file for table '/tmp/#sql_1cdc_0.MYI'; try to repair it
网上给出的原因倾向于MySQL的tmpdir的临时目录磁盘空间不足,如果检查确实时空间不足,请调整量tmpdir和slave_load_tmpdir,然后重启mysql服务.调整的方法是 locate ...
- 大型企业都在用的Python反爬虫手段,破了它!
SVG 映射反爬虫 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人 ...
- LinuX操作系统基础------> 用户管理,grep搜索
用户管理 用户组管理 字符管理和grep搜索 1.用户管理: LinuX是一个多用户,多任务的操作系统,可以让多个用户使用,这个账号可以帮助对用户进行追踪,必须在初始化的时候设置好自己的密码 1-1配 ...
- 理解HTTP的POST和PUT的区别
1.HTTP Methods HTTP Methods GET POST PUT HEAD DELETE PATCH OPTIONS GET is used to request data from ...
- 【工具】之002-Mac下常用工具
写在前面 我很懒,,,不想敲一个命令一个命令敲... "偷懒是有前提的,不是之前,就是之后." 常用命令 测试端口是否畅通 nc -z 10.254.3.86 30003 查看端口 ...
- Springboot中如何自定义注解以及使用2例
不说废话,直接进入正题: java自定义注解主要有3步:1.编写@interface接口2.编写@interface对应的处理方法进行处理3.调用处理方法 示例一:判断奇偶:比如有一个字段no要判断奇 ...
- 在java中,怎样创建编写javascript的环境?
刚开始还没有学到这一块的时候,预习的时候也是在网上搜索这一类的信息时候, 可是都是八竿子碰不到边的!在此也是呕心沥血的为读者献上最好的: 1.首先:点击空白处>右键>project: 2. ...
- python设计模式之代理模
python设计模式之代理模式 在某些应用中,我们想要在访问某个对象之前执行一个或多个重要的操作,例如,访问敏感信息--在允许用户访问敏感信息之前,我们希望确保用户具备足够的权限.操作系统中也存在类似 ...