GeekBand:Oc第二周学习笔记

2016-10-07  本文已影响0人  MingweiLee

认识oc字符串NSString

NSString是一个Unicode编码、16位字符的字符序列
NSString被定义为类,引用类型,拷贝时具有引用语义
初始化方法:字面量初始化、初始化器、工厂方法
NSString拥有恒定性,所有的操作无法更改字符串本身,如有更改都是返回新值的形式
NSString拥有共享机制,引用计数管理对其有特殊的管理规则
<small>恒定性与共享机制相辅相成,正因为有了共享机制,才需要恒定性来保证原字符串不发生变化。同时共享机制也为系统内存管理带来了很大的好处,通常应用中字符串的用量很大,如果每个相同的字符串都有一个自己的内存空间,那就会造成很大的资源浪费。所以,在oc中,当我们申明一个字符串,而这个字符串在内存中已经存在,那么该指针就会指向已存在的字符串地址上</small>

NSMutableString

NSMutableString具有可变性,NSString具有恒定性
NSMutableString为NSString的子类
NSMutableString不具有共享性,NSString具有共享性
NSMutableString并不是在原有内存上直接增长,而是重新分配一个更大或更小的缓存容量存放字符

数组 列表 字典

<small>- 类型差不多,这里主要详细讲数组</small>

认识数组:

常用操作:

//使用enumerateObjectsUsingBlock快速迭代,比起forloop要快。但是要再block中如果需要改变外部变量,那么需要在外部变量前声明__block
```

可变数组(NSMutableArray)

1.NSMutableArray支持更改数组长度和元素指针。为NSArray子类。
2.NSMutableArray初始化后,会分配一个缓存容量capacity,一般大于实际元素数量,当长度增长时,如实际需求大于capacity,其capacity会以近似二倍的方式指数增长。伴随代价:(1)分配新的堆内存2*capacity (2)将原来堆内存上的元素拷贝到新内存(3)释放原来的堆内存
3.最佳实践:估计好capacity,预先分配一定容量,避免以后增长
4.尽量避免使用insertObject:atIndex:和removeObjectAtIndex:等操作,因为会改变数组元素序列,涉及大量内存拷贝操作,代价高。

ARC

自动引用计数(Automatic Reference Counting)是OC默认的内存管理机制,针对堆上的对象,由编译器自动生成操作引用计数的指令(retain和release),来管理对象的创建与释放
新创建一个对象时,它的引用计数为1,retain操作计数+1,release-1;
当一个对象的引用计数变为0的时候,内存自动释放

自动释放池(Autorelease Pool)

release会导致对象立即释放。如果频繁对对象进行release,可能会造成琐碎的内存管理负担。autorelease可以将release的调用延迟到自动释放池被释放时。
推荐使用自动释放池(Autorelease Pool)Block,当其结束时,所有接受autorelease消息的对象将会被立即释放
大多数情况下,这样使用就行了,无需程序员干预

何时需要手工管理Autorelease Pool?
1.编写的程序不基于UI框架,如命令行程序

@autoreleasepool {
       block块
       todo   

}

2.在循环中创建大量临时对象,需要更早地释放,避免临时对象聚集导致内存峰值过大
3.在主线程之外创建新的线程,在新线程开始执行处,需要创建自己的Autorelease Pool。
4.可以嵌套使用AutoreleasePool

认识协议 Protocol

OC学习篇之---协议的概念和用法

协议:类型的合同约定,只描述外部申明,不提供具体实现。所以只有h文件
协议可以包含以下成员:
1.属性
2.实例方法
3.类方法
4.初始化器——不常用
5.析构器——不常用
协议中无法包含实例变量成员(实例变量是在m文件中)
协议中定义的属性本质上是访问器方法,编译器不会合成实例变量

使用协议

@interface ClassName : NSObject<ProtocolName>
在声明类文件时 ,在类名后面用<ProtocolName>
一个类遵守协议,需要实现协议约定的所有@required成员
<small>协议中的属性须在实现类的.h文件中申明(编译器合成实例变量需要,而方法可以省略)</small>
注意编译警告信息:
遵守协议后却没有实现必选协议方法时,会出现警告提示
协议类型变量被赋值非协议类型对象时,会出现警告提示

协议本质上是一种类型,可以作为声明类型,但不能创建实例

检查协议类型
使用conformToProtocol:检查对象是否实现了协议
if([obj conformToProtocol:@protocol(Aprotocol)])

OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字更形象点,因为我们在学习Java中的接口时候,看可以知道其实接口就相当于一种契约(协议),给他的实现类打上标记了,当然这个活在Java5.0之后,被注解替代了,因为注解就是为了此功能诞生的。
协议就是定义了一组方法,然后让其他类去实现
下面来看代码:
WithProtocol.h

#import <Foundation/Foundation.h>  

@protocol WithProtocol <NSObject>

//默认是必须实现的

//必须实现
@required

  • (void)finshTask;

//可选实现
@optional

@end

>
>这里就定义了一个协议WithProtocl
协议的定义格式:

@protocol 协议名 <父协议>
定义方法
@end

- 注:定义协议的关键字是@protocol,同时协议也是可以继承父协议的
>
协议中定义的方法还有两个修饰符:
@required:这个表示这个方法是其他类必须实现的,也是默认的值
@optional:这个表示这个方法对于其他类实现是可选的
这个就和类似与Java中的抽象类了,如果是abstract修饰的就必须实现,所以如果一个协议中没有@optional修饰的方法,那么这个协议就相当于Java中的接口了。
>
- 这里要注意的是,上面的代码中NSObject不是我们之前说的NSObject类了,而是NSObject协议,他也是OC中第一个协议,这个名字相同在OC中是没有关系的。
再看一下协议的使用:

>```
>**Student.h**
>#import <Foundation/Foundation.h>  
>  
>#import "WithProtocol.h"  
>  
>@interface Student : NSObject <WithProtocol>  
>  
>- (void)study;  
>  
>@end
>```  
- 使用协议很简单,直接在继承类(NSObject)后面 <协议名>即可
>

>```
>#import "Student.h"  
  
>@implementation Student   
- (void)study{  
    NSLog(@"study");  
}  
//直接在.m文件中实现即可,不需要在.h文件中再次定义  
#pragma mark - WithProtocol  
//一般协议的方法,在这里标记下,用途是在导航栏快速地定位到这个方法是协议里的,起到分类的作用
- (void)finshTask{  
    NSLog(@"完成任务");  
}  
>- (void)dontLate{  
//#warning 代码过几天在补充  
    NSLog(@"不迟到");  
}    
>- (void)wearNeat{  
    NSLog(@"穿戴整洁");  
}    
>@end 

类别 Categroy

类别支持在没有源代码的情况下,基于某些特定场合,为一个类增加功能
可以添加:1.类方法;2.实例方法;3.重写基类方法
不能添加:1.属性;2.实例变量;3.已存在的同名方法
命名规范:类名+扩展方法,如:NSString+Drawing.h/.m

使用类别:

1.使用场景:

2.添加类别:

BLNPoint.h
#import <Foundation/Foundation.h>
@interface BLNPoint : NSObject
{
   float _weight;
}

@property NSInteger x;
@property NSInteger y;
-(void)move;

@end

BLNPoint+Drawing.h
#import <Foundation/Foundation.h>
#import "BLNPoint.h"

@interface BLNPoint(Drawing)
-(void)draw;
//@property NSInteger weight;
-(void)setWeight:(NSInteger)weight;
-(NSInteger)weight;
@end

扩展Extension

扩展支持在编译时、有类的源代码的情况下,向类添加功能。可以将扩展看做匿名的类别
接口定义在.m文件中@implementation前声明,实现代码仍然在@implementation中实现
扩展支持添加以下成员:

@interface ClassName()
{
 声明定义
}
@end

@implementation ClassName
{
 具体实现
}
@end

使用扩展:

上一篇 下一篇

猜你喜欢

热点阅读