黑马程序员-IOS基础之OC框架(Foundation)

<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!


Foundation框架

<一>、结构体

Foundation框架是所有iOS框架的基础。
Foundation框架包含了很多开发中常用的数据类型。如:
1、结构体
2、枚举
3、类
即,要想使用Foundation框架中的数据类型,包含它的主头文件,#import <Foundation/Foundation.h>

常用结构体的介绍
1、结构体 NSRange

实质是:
typedef struct _NSRange
{
    NSUInteger location;	//位置
    NSUInteger length;		//长度
} NSRange;

NSUInteger类型的实质:typedef unsigned long NSUInteger;

应用:“love”这个单词在@“i love iOS” OC字符串中的范围。
代码如下:
NSString *str = @"i love iOS";
//第一种方法:(开发中不常用)
NSRange r1 = { 2, 4 };
//第一种方法:(开发中不常用)
NSRange r2 = { .location = 2, .length = 4};
//第三种方法:
NSRange r3 = NSMakeRange(2,4);

2、结构体 NSRange 简单使用

NSString 字符串类 继承自NSObject,遵守了协议
@interface NSString : NSObject <NSObject>
- (NSUInteger) length;
- (NSUInteger) characterAtIndex:(NSUInteger) index;
@end

//分类
@category NSString (NSStringExtensionMethods)

//...提供了很多方法

@end

创建一个简单的字符串(在OC中不管是中文还是英文都占一个字节)
NSString *str  = @"i love iOS";
查找某个字符串的范围,使用rangeOfString : (NSString *)方法,如果字符串找不到,该方法会返回:length = 0,location = NSNotFound.
查询出“love”这个字符串在str字符串中的范围。
NSRange range = [str rangeOfString : @"love"];
NSLog(@"loc = %ld, length = %ld",range.location, range.length);

3、结构体 NSPoint、NSSize、NSRect 简介

NSPoint 等价于 CGPoint (在开发中使用CGPoint,因为CGPoint跨平台)
NSPoint实质是:

typedef struct _NSPoint
{
    CGFloat x;
    CGFloat y;
} NSPoint;

typedef CGPoint NSPoint;

CGPoint实质是:

struct CGPoint
{
    CGPoint x;
    CGPoint y;
};

typedef struct CGPoint CGPoint;

CGFloat类型

#define CGFLOAT_TYPE double;
typedef CGFLOAT_TYPE CGFloat;

代码:
CGPoint p1 = NSMakePoint(10,10);
//所使用的函数为NSMakePoint(CGFloat x,CGFloat y)

//不常用的方法有:

CGPoint p = {10,10};
CGPoint p2 = {.x = 10, .y = 10};

NSPoint p3 = CGPointMake(20,20);

NSSize实质是:
typedef struct _NSSize
{
    CGPoint width;
    CGPoint height;
} NSSize;
typedef CGSize NSSize;

常使用的方法:
NSSize s1 = CGSizeMake(100,50);
CGSize s2 = NSMakeSize(100,50);
NSSize s3 = NSMakeSize(100,50);

NSRect实质是:
typedef struct _NSRect
{
    NSPoint origin;
    NSPoint size;
} NSRect;

创建方法:
CGRect c1 = CGRectMake(0,0,100,50);

将结构体转成NSString类型
CGPoint p1 = NSMakePoint(10,10);
NSString *str = NSStringFromPoint(p1);
NSLog(@"%@",str);

4、结构体 NSPoint、NSSize、NSRect 其他用法

创建CGRect的另一种方式
CGRect r2 = { { 0, 0}, { 100, 90} };
如果要使用原点
CGPointMake(0,0) 等价于 CGPointZero
CGRect r3 = { CGPointZero, CGSizeMake(100,90)}

//比较两个点是否相同
CGPointEqualToPoint(CGPoint point1,CGPoint point2);
//比较两个长度是否相同
CGSizeEqualToSize(...)
//比较两个矩形是否相同
CGRectEqualToRect(...)

//项目中可能出现的问题
undefined symbols for architecture x86_64:"_CGRectContainsPoint",referenced from _main in main.o

//原因:从以上方法中,我们可以看出,好多方法都是以CG开头的,所以我们要引入CoreGrapgics框架

<二>、字符串类

Foundation框架中的常用的类:NSString、NSArray、NSSet、NSDictionary、NSDate、NSObject

1、字符串类NSString

字符串的创建

第一种方式:
NSString *s1 = @"jack";
第二种方式:
NSString *s2 = [ [NSString alloc] initWithString:@"jack"];
第三种方式:
NSString *s3 = [ [NSString alloc] initWithFormat:@"age is %d",10];
第四种方式:
把C语言中的字符串转成OC中的字符串
NSString *s4 = [ [NSString alloc] initWithUTF8String:"jack"];
把OC中的字符串转成C语言中的字符串
const char *c = [s4 UTF8String];
(不写编译器会发出警告,因为UTF8String方法的返回值是const char *)

从文件内容中获取字符串的方法有
initWithContentOfFile:(NSString *) encoding:(NSStringEncoding) error:...
initWithContentOfFile:(NSString *) usedEncoding:(NSStringEncoding) error:...
//URL:资源路径(只要是资源,就可以获取,万能的)
initWithContentOfURL:(NSURL *)encoding:(NSStringEncoding) error:...

协议头://路径
file://
ftp://

把一个字符串变成URL对象
NSURL *url = [ [NSURL alloc] initWithString:@"..."];
以上全都是对象方法的实现,其实在开发中我们常使用的类方法,如
[NSString stringWithFormat:@""];
[NSString stringWithContentsOfFile:];
一般都会有一个类方法跟对象方法配对。

[NSURL fileURLWithPath:@"..."];
//file就代表文件资源

将字符串写进文件(如果文件不存在会自动创建)
[@"..." writeToFile:(NSString *s) ...];
方法中参数说明:atomically:YES
原子性操作,写YES,如果发现文件写入了一半,但写入失败的话,该文件就不会创建。

将字符串写进URL
[@"..." writeToURL:...];

NSMutableString 继承自 NSString

NSMutableString 可变字符串
NSString 不可变字符串

创建可变字符串
NSMutableString *s1 = [NSMutableString stringWithFormat:@"age is %d",10];

为s1字符串拼接字符串的方法有
appendFormat、appendString
[s1 appendFormat:@" 11 12"];

删除s1中的某些字符
[s1 deleteCharactersInRange:NSMakeRange(4,2)];

获取某个字符串的范围
NSRange range = [s1 rangeOfString:@"is"];

不可变字符串NSString,也可以拼接,但是会返回新的字符串,原来的不变。
[s1 stringByAppendingString:@"..."];
原理:是将s1字符串的内容拷贝一份,然后把拼接好的字符串返回,原来s1字符串的内容不变。

<三>、数组

三个集合类:NSArray、NSSet、NSDictionary

C语言中的数值,只能存相同的数据类型。所以,就有了OC数组。 而OC数组的唯一缺点:就是不能存放基本数据类型,如int、double、float、char、struct、enum等,也不能存放nil值。如果要存基础类型的数据,就必须将基本数据类型转成OC中的NSNumber类型

NSArray数组

第一种方式:
NSArray *array = [NSArray array];
//array永远是空数组

第二种方式:
NSArray *array2 = [NSArray arrayWithObject:@"jack"];
//array2数组里只有一个元素

第三种方式:
NSArray *array3 = [NSArray arrayWithObjects:...,nil];
//创建多个元素的数组

计算数组的个数:
[array3 count]
等价于array3.count

获取数组中某个位置的元素
[array3 objectAtIndex:1];
也可以这样写:array3[0]    (编译器特性)

快速创建一个数组(也是编译器特性)
NSArray *array4 = @[@"jack",@"rose",@"tom"];

NSArray数组元素的遍历

创建一个数组
Person *p = [ [Person alloc] init];
NSArray *array = @[p,@"jack"];

第一种遍历的方式:
for(int i = 0; i < array.count; i++)
{
    NSLog(@"%@",array[i]);
}

第二种遍历方式:
for(id obj in array)
{
    //位置
    int i = [array indexOfObject:obj];
    NSLog(@"%@",obj);
}
//id obj 代表着数组中的每一个元素
//缺点:不知道当前循环是第几次

第三种遍历方式:
[array enumrateObjectUsingBlock:^(id obj,NSUInteger idx,BOOL *stop)];
//每遍历到一个元素,就会调用一次block,并且当前元素和索引位置当做参数传给block

Block回忆:
int (^sumBlock)(int,int) = ^(int a,int b){
    return a + b;
}
sumBlock(10,12);
//其实就相当于把它当做方法的参数

猜测enumrateObjectUsingBlock方法的实现

for(int i = 0; i < array.count; i++)
{
    //用来标记是否需要停止遍历
    BOOL isStop = NO;
    //取出元素
    id obj = array[i];
    //for循环外面有个block
    myblock(obj,i,&isStop);
    if(isStop)
    {
        break;
    }

}

NSMutableArray 继承自 NSArray

NSMutableArray的基本使用

//创建一个空数组
NSMutableArray *array = [NSMutableArray array];
//为空数组添加元素
[array addObject : [ [Person alloc] init] ];
[array addObject : @"jack"];

//错误写法(不能在数据中添加空对象)
[array addObject : nil];

//在创建的同时初始化
NSMutableArray *array = [NSMutableArray arrayWithObjects : @"jim",@"rose",nil];

//删除所有元素
[array removeAllObjects];

//删除某个元素
[array removeObject : @"jack"];

//删除指定位置的元素
[array removeObjectAtIndex:1];

//错误有
NSMutableArray *array = @[@"jack",@"rost"];
@是编译器特性,@的返回值是NSArray
经典错误:unrecognized selector sent to instance

NSMutableSet 继承自 NSSet

//创建一个永远为空的NSSet
NSSet *s = [NSSet set];

//NSSetde类方法有:
+ (id)setWithArray:(NSArray *)
//传多个元素初始化set
+ (id)setWithObjects:(id),...,nil
+ (id)setWithObjects:(const id *)
//只传一个元素初始化set
+ (id)setWithObject:(id)
+ (id)setWithSet:(NSSet *)

//随机返回一个元素
[s anyObject];

//创建一个空NSMutableSet
NSMutableSet *s = [NSMutableSet set];
//为空集合添加元素
[s addObject:@"jack"];
//删除元素的两个方法
[s removeObject:@"jack"];
[s removeAllObjects];

总结:

NSSet 和 NSArray的对比
1、共同点
①、都是集合,都能存放多个OC对象。
②、只能存放OC对象,不能存放非OC对象类型(基本数据类型,如:int、float、double等,结构体,枚举)
③、本身都不可变,都有一个可变的子类
2、不同点
①、NSArray有顺序,NSSet没有顺序。

NSMutableDictionary 继承自 NSDictionary

字典:
key  ------value
索引------文字内容
里面存储的东西都是键值对

//创建一个字典
NSDictionary *dit = [NSDictionary dictionaryWithObject:@"jack" forKey:@"name"];

id obj = [dict objectForKey:@"name"];

为了让字典初始化时,有更多的键值对,使用如下方法创建字典对象
dictionaryWithObjects:objects forKey keys

其中,objects、keys皆为数组NSArray

使用编译器特性,快速创建字典对象
NSDictionary *dict = @{
@"name" : @"jack",
@"address" : @"Beijing"
};
//计算字典元素的个数(键值对的个数)
dict.count

//创建一个可变的字典对象
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
为字典对象添加键值对的方法是:
setObject:(NSString *) forKey:(NSString *);
而并不是add方法
[dict setObject:@"jack" forKey:@"name"];

字典的删除方法集合有
removeAllObjects
removeObjectForKey:(id)
removeObjectsForKeys:(NSString *)

遍历字典中的键值对
NSArray *keys = [dict allKeys];
for(int i = 0; i < dict.cout; i++)
{
    NSString *key = keys[i];
    NSString *object = dict[key];
}

字典中标不允许有相同的key,但允许有相同的value

集合总结:

OC中的集合 JAVA中的集合
NSArray ArrayList
NSSet HashSet
NSDictionary HashMap

1、NSArray\NSMutableArray
①、有序
②、快速创建(不可变):@[obj1,obj2,obj3]
③、快速访问元素:数组名[i]

2、NSSet\NSMutableSet
①、无序
②、没有快速创建

3、NSDictionary\NSMutableDictionary
①、无序
②、快速创建(不可变):@{ key1 : value1, key2 : value2};
③、快速访问元素:字典名[key]

都不能存放空值。

NSNumber类

在实际开发中,我们要将基本数据类型存到数组中,我们就需要用到NSNumber
NSNumber类方法(将基本数据类型转成NSNumber对象)

+ (NSNumber *)numberWithBOOL:(BOOL)
+ (NSNumber *)numberWithChar:(char)
+ (NSNumber *)numberWithDouble:(double)
+ (NSNumber *)numberWithFloat:(float)
+ (NSNumber *)numberWithInt:(int)
+ (NSNumber *)numberWithInteger:(NSInteger)
+ (NSNumber *)numberWithLong:(long)
+ (NSNumber *)numberWithLongLong:(long long)

例:
//将C语言中的基本数据类型转成OC中的NSNumber类型
NSNumber *num = [NSNumber numberWithInt:10];
//然后将转好的NSNumber类型放到字典中
NSDictionary *dict = @{
@"name" : @"jack",
@"age" : num
};

NSNumber *num2 = [dict objectForKey:@"age"];

错误写法:
int age = dict[@"age"];

如何将OC中的NSNumber类型转换成C中的基本数据类型

有如下方法

@interface NSNumber : NSValue
- (char)charValue; 
- (short)shortValue; 
- (int)intValue;
- (long)longValue;  
- (long long)longLongValue; 
- (float)floatValue; 
- (double)doubleValue; 
- (BOOL)boolValue;
@end

将C中的int类型转成NSString
NSString *str = [NSString stringWithFormat:@"20"];
将NSString转成C中的int
int a = [str intValue];

 

NSNumber之所以能包装,是因为它继承自NSValue,而NSNumber只能包装基本数据类型,如:int、double、float、char、等,但枚举,结构体就得用NSValue包装了。

NSValue的类方法有:
+ (NSValue *)valueWithPoint:(NSPoint)
+ (NSValue *)valueWithPointer:(const void *)
+ (NSValue *)valueWithRange:(NSRange)
+ (NSValue *)valueWithRect:(NSRect)
+ (NSValue *)valueWithSize:(NSSize)

例:将结构体转成OC对象
CGPont p = CGPointMake(10,10);
NSValue *value = [NSValue valueWithPoint:p];
NSArray *array = @[value]; 

NSDate类

//创建一个时间对象(代码执行的当前时间)
NSDate *date = [NSDate date];

//这句代码的时间比上一句代码晚5秒
NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];

//从1970年开始走过的秒数
NSTimeInterval seconds = [date2 timeIntervalSince1970];

//自调用代码与当前时间的差
NSTimeInterval seconds2 = [date2 timeIntervalSinceNow];

将日期输出:日期----->NSString对象
NSDate *date = [NSDate date];
//日期格式化类
NSDateFormatter *formatter = [ [NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *str = [formatter stringFromDate:date];

//将NSString对象------>日期
[formatter dateFromString:time];



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值