OC-Foundation

Foundation 框架是其他所有iOS框架的基础

  • 包含了很多开发中常用的数据类型
    • 结构体
    • 枚举
  • 要想使用Foundation中的数据类型,包含它的主文件即可#import <Foundation/Foundation.h>

1. 结构体 常用 NSRange CGPoint CGSize CGRect

  • NSRange
typedef struct _NSRange{
    NSUInteger location;
    NSUInteger length;
} NSRange;

NSRange r = {2, 3}; // 不用
NSRange r2 = {.location = 2, .length = 3}; // 不用

NSRange r3 = NSMakeRange{2, 3}; // 掌握 !!!

NSString *str = @"VampireJune";

// 查找某个字符串在 str 中的范围
// 如果找不到,length = 0,location = NSNotFound == -1
NSRange r4 = [str rangeOfString:@"June"];
NSLog(@"loc = %ld, len = %ld", r4.location, r4.length);

  • NSPoint == CGPoint (跨平台的(Mac 和 iOS),只用这个) 表示一个点的位置
struct CGPoint{
    CGFloat x;
    CGFloat y;
};

typedef struct CGPoint CGPoint;

CGPoint p = NSMakePoint(10, 10);
// 最常用的方法 CGPointMake
NSPoint p1 = CGPointMake(20, 20);

// 表示原点
CGPointZero == CGPointMake(0, 0);
// 还有 CGSizeZero, CGRectZero

// 使用这些函数的前提是添加 CoreGraphics 框架
// 比较两个点是否相同 (x, y)
BOOL B = CGPointEqualToPoint(CGPointMake(20, 20),CGPointMake(20, 20))
// 还有 CGSizeEqualToSize,CGRectEqualToRect
  • NSSize == CGSize 表示UI元素尺寸
NSSize  s  = CGSizeMake(20, 20);
NSSize  s1 = NSMakeSize(20, 20);
CGSize  s2 = NSMakeSize(20, 20);

struct CGSize{
    CGFloat width;
    CGFloat height;
}

typedef struct CGSize CGSize;
  • NSRect == CGRect 代表二维平面中的某个物体的位置和尺寸
struct CGRect{
    CGPoint origin;
    CGSize  size;
};
 
CGRect  r1 = CGRectMake(0, 0, 100, 20);
// 超麻烦
NSLog(@"x = %f, y = %f, width = %f, height = %f", 
r1.origin.x, r1.origin.y, r1.size.width, r1.size.height);

// 将结构体转为字符串
// NSString *st = NSStringFromRect(r1);
NSLog(@"%@",st);

// 还有NSStringFromPoint, NSStringFromSize


CGRect myRect (CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
    CGRect rect;
    rect.origin.x = x;
    rect.origin.y = y;
    rect.size.width = width;
    rect.size.height = height;

    return rect;
} 

// 多种写法
CGRect  r2 = {{0, 0}, {100, 20});
CGRect  r3 = {p, s);
CGRect  r3 = {CGPointZero, CGPointMake(20, 20)};

// 使用这个函数的前提是添加 CoreGraphics 框架
// 判断一个矩形范围是否包含坐标20 ,20的点
CGRectContainsPoint(CGRectMake(0, 0, 100, 20),CGPointMake(20, 20));

2. 常用类 NSString NSArray NSSet NSDictionary NSDate NSObject

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

NSString *s1 = @"VampireJune";

NSString *2 = [[NSString alloc] initWithFormat:@"is %d",10];

// 类方法创建 字符串
[NSString stringWithFormat:@"is %d",10];

// C字符串 --> OC字符串  
NSString *s3 = [[NSString alloc] initWithUTF8String:"VampireJune"];

// OC字符串 --> C字符串
const char *cs = [s3 UTF8String];

// 从文件中读取字符串
// NSUTF8StringEncoding 用到中文就可以用这种编码
NSString *s4 = [[NSString alloc] initWithContentsOfFile:"/绝对路径" encoding:NSUTF8StringEncoding error:nil];


// URL : 资源路径 
// 协议头 : //路径(file://、ftp://)
NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/apple/Desktop....."];

// 类方法
[NSURL urlWithString:@"file:///Users/apple/Desktop....."];

// 省去了协议头
[NSURL fileURLWithPath:@"/Users/apple/Desktop....."];


NSString *s5 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

// 一般都会有一个类方法跟对象方法配对

// 字符串导出到文件
// atomically : 原子性操作,
  * YES,当文件写了部分失败了,这个文件不会创建
  * NO ,当文件写了部分失败了,这个文件还会创建
[@"Vampire\nJune" writeToFile:@"文件路径" atomically:YES encoding:NSUTF8StringEncoding error:nil];

// 不可变字符串后拼接一个字符串,返回一个新字符串对象
NSString *s6 = [NSString stringByAppendingString:@"..."];
  • NSMutableString 可变字符串 继承自 NSString
// 拼接内容到 s1 的后面
[s1 appendString:@"..."];

// 删除 Range 的内容 VampireJune
NSRange ra = [s1 rangeOfString:@"VampireJune"];
[s1  deleteCharactersInRange: ra];

3. 集合类 NSArray NSSet NSDictionary

  • NSArray
// OC数组只能存放 OC 对象,不能存放 非OC对象类型,如,int、struct、enum等,不能存放 nil 值

// 创建不可变数组
// nil 是数组元素结束的标记 
NSArray *array = [NSArray arrayWithObjects:@"Vampire",@"June",nil];

// 编译器特性,快速创建OC数组
NSArray  *array1 = @[@"Vampire",@"June"];

// 获取数组的个数
[array count]; == array.count

// 拿取位置 1 的元素
[array objectAtIndex:1]; == array[1];(编译器特性,转成前面代码)

遍历 1
Person *p = [[Person alloc] init];
NSArray  *array = @[p,@"June"];

for (int i = 0; i < array.count; i++)
{
    NSLog(@"%@", array[i]);
}

遍历 2 快速遍历
for (id obj in array)
{
    // 找出 obj 元素在数组中的位置
    NSUInteger i = [array indexOfObject:obj];

    NSLog(@"%@ -- %ld", obj, i);

    if(i == 1)
    {
        // 停止遍历,退出循环
        break;

///** 注  break 只用在 switch语句 和 for循环
    }
}

遍历 3 block遍历
[array enumerateObjectsUsingBlock:

// 每遍历到一个元素,就会调用一次 block
// 并且把当前元素和索引位置当做参数传给 block
^(id obj, NSUInteger idx, BOOL *stop)
{
    if(idx == 1)
    {
        // 停止遍历
        *stop = YES;
    }
}];

遍历 3 block遍历 的本质 解释

void ^(myBlock)(id, NSUInteger, BOOL *) = ^(id obj, NSUInteger idx, BOOL *stop)
{

}

for (int i = 0; i < array.count; i++)
{
    // 用来标记是否需要停止遍历
    BOOL isStop = NO;

    // 取出元素
    id obj = array[i];

    myBlock(obj, i, &isStop);

    if(isStop)
    {
        break;
    }
}

  • NSMutableArray 可变数组 继承自 NSArray
NSMutableArray *array = [NSMutableArray array];

[array addObject:]; // 添加元素

// 错误  [array addObject:nil];

[array removeObject:]; // 删除元素
  • 集合的内存管理 (MRC里)
NSMutableArray *array = [NSMutableArray array];
Person *p = [[Person alloc] init];

// 当把一个对象添加到集合中时,这个对象会做一次 retain 操作,计数器会 +1
// 当把一个对象从集合中移除时,这个对象会做一次 release 操作,计数器会 -1
[array addObject:p];

[p release];

// 当一个集合被销毁时,会对集合里面的所有对象做一次 release,里面的所有对象的计数器会 -1
[array release];

// 泛型 指定数组类型
@property (nonatomic, strong) NSMutableArray <NSString *> *names;
  • NSSet NSMutableSet 无顺序的集合
NSSet *s = [NSSet setWithObjects:@"Vampire",@"June",nil];

[s anyObject]; // 随机取出一个元素

NSMutableSet *s2 = [NSMutableSet set];
  • NSSetNSArray 的对比

    • 共同点
      • 都是集合,都能存放多个OC对象
      • 只能存放OC对象不能存放非OC对象类型(基本数据类型:intcharfloat等,结构体枚举

    -不同点

    • NSArray 有顺序
    • NSSet 无顺序
  • NSDictionary NSMutableDictionary 字典

    • key ---> value

    • 索引 ---> 文字内容

    • 里面存储的东西都是 键值对

      • 不允许相同key,但允许有相同的 value
      • 无顺序
NSDictionary *dic = [NSDictionary dictionaryWithObject:@"June" forKey:@"name"];

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

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"June", @"name", @"地址", @"address",nil ];

NSDictionary *dic = @{@"June": @"name", @"地址": @"address"};
id obj = dic[@"name"];

dic.count // 返回的是 键值对 的个数


NSMutableDictionary *dic = [NSMutableDictionary dictionary];

[dic setObject:@"jack" forKey:@"name"]; // 添加键值对

 // 字典中只允许有一个 key,设置已经有的key,value,原来的会被覆盖
[dic setObject:@"Vampire" forKey:@"name"];

[dic removeObjectForKey"@"name"]; // 移除键值对

// 遍历字典 1
NSArray *keys = [dic allKeys];
for (int i = 0; i < dic.count; i++)
{
    NSString *key = keys[i];
    id obj *value = dic[key];
    NSLog(@"%@ -- %@",key ,value);
}

// 遍历字典 2
[dic enumerateKeysAndObjectsUsingBlock:
^(id key, id obj, BOOL *stop)
{
    // 停止遍历
    *stop = YES;
}];
  • 集合对比
OC JAVA
NSArray List
NSSet Set
NSDictionary Map
1. NSArray\ NSMutableArray
* 有序
* 快速创建(不可变):@[obj, obj1, obj2];
* 快速访问元素:数组名[i]

2. NSSet\ NSMutableSet
* 无序

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

4. 泛型 指定 key value 类型

@property (nonatomic, strong) NSMutableDictionary <NSString *, NSNumber *> *names;
  • NSNumber
// @10 是将 10 包装成一个 NSNumber 对象 
NSNumber *num = [NSNumber numberWithInt:10]; == @10

int a = [num intValue];

// 将 age 包装成一个 NSNumber 对象 
int age = 100; 
[NSNumber numberWithInt:age] == @(age)


// NSNumber 之所以能包装基本数据类型为对象,是因为继承了 NSValue

NSValue 可以包装任意值

// 结构体 ---> OC对象
CGPoint p = CGPointMake(10, 10);
// 将结构体转为 Value 对象
NSValue *vv = [NSValue valueWithPoint:p];

// 将 value 转为对应的结构体
[vv pointValue];
  • NSDate
// 创建一个时间对象 当前时间 0时区时间(北京-东8区)
NSDate *date = [NSDate date];

// 比 date 时间 晚 5 秒
NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];

// 从 1970 开始到 date2 走过多少秒
NSTimeInterval seconds = [date2 timeIntervalSince1970];

[date2 timeIntervalSinceNow];

// 日期格式化类 NSDateFormatter
NSDateFormatter *f = [[NSDateFormatter alloc] init];
// 设置格式
// y年  M月  d日  Z时区
// m分  s秒  H(24)时  h(12)时
f.dateFormat = @"yyyy-MM-dd HH:mm:ss"
[f stringFormDate:date];


// 创建一个日历对象
NSCalendar *calendar = [NSCalendar currentCalendar];
// 利用日历对象 或者 时间对象 对应的 年、月、日、时分秒
int unit = NSCalendarUnitYear | NSCalendarUnitMonth;
NSDateComponents *c = [calendar components:unit  formDate:now];

// 打印时间的要素
NSLog(@"%ld", c.year);

// 利用日历,比较 时间 差距 
NSString *time1 = @"2014-04-08 20:50:40";
NSString *time2 = @"2014-04-04 18:45:30";

NSDateFormatter *f = [[NSDateFormatter alloc] init];
f.dateFormat = @"yyyy-MM-dd HH:mm:ss";

NSDate *date1 = [f dateFormString;time1];
NSDate *date2 = [f dateFormString;time2];

// 创建一个日历对象
NSCalendar *calendar = [NSCalendar currentCalendar];


int unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;

NSDateComponents *c = [calendar components:unit  formDate:date1 toDate:date2 options0];

NSLog(@"相差%ld年%ld月%ld日%ld时%ld分%ld秒",c.year, c.month, c.day, c.hour, c.minute, c.second);

5. NSFileManager 用来进行常见的文件\文件夹操作

  • NSFileManager 使用了 单例 模式
  • 使用 defaultManager 方法可以获得单例对象
NSFileManager *mgr = [NSFileManager defaultManager];

// 默认不是文件夹,即默认是文件
BOOL dir = NO;
// isDirectory 判断是否是个文件夹 需要传 dir 的地址,可以改变 dir 的值,返回值代表 是文件还是文件夹
// 返回值 exist 代表这个路径的文件\文件夹是否存在
BOOL exist = [mgr fileExistsAtPath:@"路径" isDirectory:&dir];

// 获得文件、文件夹的属性
NSDictionary *attr = [mgr attributesOfItemAtPath:@"路径" error:nil];

// 获得当前文件夹下面有哪些内容
NSArray *contents = [mgr contentsOfDirectoryAtPath:@"路径" error:nil];

// 获得当前文件夹下面 所有子路径
NSArray *contents = [mgr subpathsOfDirectoryAtPath:@"路径" error:nil];

6. Copy MutableCopy

  • 作用:利用一个源对象产生一个副本对象
  • 特点:修改源对象的属性和行为,不会影响副本对象
  • 使用:一个对象可用调用 copy\mutableCopy 方法类创建一个副本对象
copy:创建的是不可变副本(如NSString、NSArray、NSDictionary)
> copy : 需要遵守 NSCopying 协议,实现 copyWithZone: 方法

@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end
mutableCopy:创建的是可变副本(如可变字符串、可变数组、可变字典)
> mutableCopy : 需要遵守 NSMutableCopying 协议
实现 mutableCopyWithZone: 方法
@protocol NSCopying
- (id)mutableCopyWithZone:(NSZone *)zone;
@end
  • 浅复制(浅拷贝,指针拷贝,shallow copy)
    • 本质是:没有产生对象
    • 源对象和副本对象是同一个对象
    • 源对象(副本对象)引用计数器 +1,相当于做一次 retain 操作
  • 深复制(深拷贝,内容拷贝,deep copy)

    • 本质是:产生对象
    • 源对象和副本对象是不同的两个对象
    • 源对象引用计数器不变,副本对象计数器为1(因为是新产生的)
  • 只有 源对象副本对象不可变时,才是 浅复制

  • 其他都是深复制

7. @property 内存管理策略的选择

  • 1.非ARC

    • copy : 用于 NSString\block (坚决不能用可变字符串)
    • retain : 除 NSString\block 以外的OC对象
    • assign : 基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端用 retain,一端用 assign
  • 2.ARC

    • copy : 用于 NSString\block (坚决不能用可变字符串)
    • strong : 除 NSString\block 以外的OC对象
    • weak : 当2个对象相互引用,一端用 strong,一端用 weak
    • assgin : 基本数据类型、枚举、结构体(非OC对象)

8. 递归

  • 1.函数自己调自己
  • 2.必须有个明确的返回值

9. static 在 OC 中的使用

  • static

  • 1.修饰局部变量

    • 让局部变量只初始化一次
    • 局部变量在程序中只有一份内存
    • 并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,才会销毁)
  • 2.修饰全部变量

    • 全部变量的作用域仅限于当前文件
  • 例:#define a 0.5 VS const CGFloat a = 0.5;

  • 像宏一样,不能改值

  • 有多少使用宏的地方,就会开辟多少临时存储空间

  • 使用 const ,就只会开辟一个存储空间

  • 还可以使用 extern 全局引用

  • 如果引用的是个常量,最好加一个,const

  • 例:extern const CGFloat a (编译阶段就能很快发现,避免修改被 const 修饰的常量,运行是崩溃)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容

  • 一滴水的笑阅读 121评论 2 1
  • 该系列主要着重于平时学习中遇到的不理解的知识点,以打磨知识点为主。没有一定的顺序,遇到不会的就学,学了就按...
    你好12388阅读 341评论 0 0
  • 我们家向来有喝酒的传统,遥记小时候,印象中的酒场典型何其多,记忆深刻的有一个中风已经半身不遂的大爷爷,每天必然3顿...
    黑土钱阅读 154评论 3 4
  • 当你能够享受现实的安稳时, 好好去获得滋养和满足; 当你的内心的欲望被激活时, 给自己机会去实现自我; 当你陷入现...
    miss喜子阅读 212评论 1 1
  • 运算符与if &&应用if(a>1) {console.log("a="+a);}上面这个函数可以写成 a>1 ...
    _v_xw阅读 150评论 0 0