OC基础知识汇总

OC部分
第一部分   基本概念 
OC概述
OC是一种能够完成复杂面向对象编程的简单的计算机设计语言。
通过提供用于定义类和方法的语法,它扩展了标准的c语言。它还提供了类和接口(任何类采用)的动态扩展。
面向对象编程
1.  面向对象 和 面向过程
面向对象 OOP( Object Oriented Programming ) 分解问题组成的对象 协调对象间的联系和通信 解决问题.  以对象为中心 也就是参数事件的参与者,设计对象的功能完成事件只是事物所有功能中的一小部分.
面向过程 POP (P rocedure Oriented  Programming)  分析解决问题的步骤 实现函数 依次调用.  事件为中心  关心该事件的详细步骤 一步一步如何完成实现.
类和对象
2.   类  只允许单继承 一个类只允许一个父类 没有父类的类称为根类  NSObject 根类 OC里唯一一个没有父类的类
:一组具有 相同特征和行为的事物的抽象集合 。 是一个抽象的概念,在生活中不具体.  静态属性 特征  动态属性 动作
对象:类中具体的。对象是类的实例。类的具体表现.
静态类型化 :可以一眼看出对象属于哪个类;  动态类型化:不可以看出继承与哪个类的对象声明方法
类和对象是面向对象的核心。
三大步骤:定义类 ,创建对象,使用对象。

3.OC中类的定义
面向对象编程中使用对象完成程序
开发中:先定义类 ,在创建对象,然后使用对象。

定义类包含两部分“:接口部分和实现部分。 分开写
1.接口部分:对外声明类的特征和行为 提供外部访问的接口 相当于说明书。 写在 .h文件中 
接口部分标志:@interface  @end
作用: 声明类的实例变量和方法,即特征和方法
包含内容:类名 父类名 实例变量 方法。
(1)以@interface 接口开头  Person 当前类名 :  NSObject  当前类继承的父类
(2)以@end//结束 只有把类的接口定义内容写在开始和结束之间才有效.
(3) People 类名 
(4) : 表示继承 后面表示它有父类 
(5) NSObject 父类名
 
2.实现部分:对内实现行为,相当于功能的实现。 实现部分写在.m文件中
(1)以@implementation开头 以@end结束 实现内容必须写在中间才有效 (2)@implementation后的people是要实现的类(需要指定对哪些类实现)
实现部分标志:@
类和文件
类:@interface...@end 文件 @implemention…@end
文件:.h称为接口文件或者头文件   .m称为实现文件。
默认设置如下:
1.使用类命名文件
2..h文件管理类的接口部分,.m文件管理类的实现部分、
文件和类本质没有关系。为了方便管理实现封装性。
4. 创建对象
创建对象分两步:分配内存空间和初始化
分配内存空间:根据类中声明的 实例变量 为对象分配内存,将所有的实例变量置为默认值0,并返回首地址
初始化:
为对象的实例变量设置初始值。
使用对象
指针存储对象的首地址,代指对象。OC中使用指针代指对象,进行操作。
Person *p =[Person alloc];先执行”=“ 右侧
1.[ person alloc] 返回值是对象的首地址,即对象。
2.p是跟对象同类型的指针变量,存储对象首地址,代指对象。
5.实例变量操作
- (CGFloat)getValuea:(CGFloat)a b:(CGFloat)b  c:(CGFloat)c;

方法只.h文件中声明  没.m文件中定义实现
解决方法 :在.m文件里实现 或者在.h里删掉
OC中方法调用 采用消息发送机制[receiver  message];
[receiver(接收者  (+) 或者 对象(-))  message(消息)];

6.  NSLog的定义

NSLog定义在NSObjCRuntime.h中,如下所示:

void NSLog(NSString *format, …);
基本上,NSLog很像printf,同样会在console中输出显示结果。不同的是,传递进去的格式化字符是NSString的对象,而不是char *这种字符串指针
NSLog可以如下面的方法使用:
NSLog (@"this is a test");
NSLog (@"string is :%@", string);
NSLog (@"x=%d, y=%d", 10, 20);
但是下面的写法是不行的:
int i = 12345;
NSLog( @"%@", i );
原因是, %@需要显示对象,而int i明显不是一个对象,要想正确显示,要写成:
int i = 12345;
NSLog( @"%d", i );
NSLog的格式如下所示:
%@对象
%d, %i整数
%u,%z无符整形
%f浮点/双字
%x, %X 二进制整数
%o八进制整数
%zusize_t
%p指针
%e浮点/双字 (科学计算)
%g浮点/双字
%sC字符
%.*sPascal字符串
%c字符
%Cunichar
%lld64位长整数(long long) 
%llu无符64位长整数
%Lf64位双字 
7. 类和对象  
 - 对于对象  +对于类 
(id) 类似于C语言中的(void *) 泛指指针的返回地址

8.  实例变量可见度 (了解)
public   公共的共有的      实例变量可以在类的外部和内部操作 访问方式可以通过 :对象 + 指向操作符 + 实例变量 例如: p->name;

protected  受保护的 默认的    实例变量只能在该本类和子类内部操作

private  私有的   实例对象只能在该类内访问,不可以在子类文件以及其他文件中访问.

实例变量定义在.h中 相当于先声明某一变量是某一类型的实例变量.  不设置可见度的时候,为默认的 受保护的 protected 定义方式  
      为什么不声明为@public :1. 外部就可以访问内部以及修改,会影响内部的一个实现,提供外不访问的接口. 2.违背了OC三大面向对象的思想——封装 隐藏内部实现,提供外界访问的借口.
     为什么不声明为@private :1.子文件访问不到,子文件还需另外声明.2.违背oc的继承父类有 子类就可以用

    @public //单独
    
NSString *name;//姓名
    
@private
    
NSString *gender;//性别
    
@protected
    
NSInteger age;//年龄

9.  类的定义
接口部分和文件实现部分可以写在main.m里 但需要写在main函数的外面 相当于函数的声明和实现
一个文件里可以有很多个类 只要符合 接口文件的声明和实现的框架就可以 和文件名没有关系 一般情况下 一个文件中就定义一个类 类的名字和文件同名
//.m
@implementation aa
@end 

//.h
 @interface aa : NSObject
 {
 NSString *name;
 NSString *sex;
 }
 @end

10.  方法
工程 所有单词的首字母都要大写 
方法 第一个不大写 以后所有的首字母都大写
//self 谁调用该方法,self就代表谁 可用于对象 也可用于类 当方法是一个减号方法时 调用该方法的对象是谁 self就是当前对象 当方法是一个加号方法时,调用该方法的类是谁 self就代表当前类 
加号方法即类方法 只能类使用 不能使用实例变量 实例变量是依托于对象存在的 只有有了对象 实例变量才会有效 这时候还没有实例方法 比如给人个名字  但不知道给那个对象赋名字

unknown type name “women”  意思:不能识别的类型women  解决方案:#import头文件时,会将头文件中的内容复制一份,二档使用women这个类时,该类还未定义,所以识别不了.典型的循环导入问题.  解决方案 :使用该类时不能把它当做一个类来使用,所以在.h文件里使用@Class women;将women声明为一个字符串使用 ,但他不具有类中的内容,需要在.m里面#import “women.h”导入头文件
.n文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
//实例变量的存在依托于对象
  
//NSString字符串的类
    
NSString *_name;//姓名
    
NSString *_gender;//性别
    
NSInteger _age;//年龄
}
//类的方法,即函数的声明,不一样的是oc的方法有对对象的和对类的
//打豆豆
+ (
void)fight;//针对与类的方法 不能有实例变量
//sayHi;
- (
void)sayHi;

//设置器方法 set开头的基本形式如下都没有返回值 都有参数 为实例变量赋值 只有一个参数
//name赋值
- (
void)setName:(NSString *)name;
//gender赋值
- (
void)setGender:(NSString *)gender;
//age赋值
- (
void)setAge:(NSInteger)age;

//访问器 get方法 都没有参数 都有返回值 给实例变量获取值
//读取_name的值
- (
NSString *)name;
//读取_gender的值
- (
NSString *)gender;
//读取_age的值
- (
NSInteger)age;

//自定义一个初始化方法 标识符 对象方法  + 类方法
- (
id)initWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age;//实例方法 又称对象方法
//id OC里面所有的返回类型,相当于 void*
//初始化方法的方法名initWhitName:gender:age:中间不能有空格 冒号不能省略
//测试函数
+ (
void)test;
@end
@interface Student : NSObject
{
    
NSString *name;
    
NSString *sex;
}
@end
@interface aa : NSObject
{
    
NSString *name;
    
NSString *sex;
}
@end
//一个文件里可以有很多个类 只要符合 接口文件的声明和实现的框架就可以 和文件名没有关系 一般情况下 一个文件中就定义一个类 类的名字和文件同名
.m文件
#import "Person.h"
@implementation Person
//打豆豆
+ (
void)fight{
   
NSLog(@"打豆豆");
}
//sayHi;
- (
void)sayHi{
    
NSLog(@"name:%@,gender:%@,age:%ld",_name,_gender,(long)_age);
}
//name赋值的实现
- (
void)setName:(NSString *)name{
    
_name = name;
}
//规范的写法 _name 实例变量前加_ + 变量名
//gender赋值
- (
void)setGender:(NSString *)gender{
    
_gender = gender;  
}
//age赋值
- (
void)setAge:(NSInteger)age{
    
_age = age ;
}
//读取_name的值
- (
NSString *)name{
    
return _name;
}
//读取_gender的值
- (
NSString *)gender{
    
return _gender;
}
//读取_age的值
- (
NSInteger)age{
    
return _age;
}
//自定义一个初始化方法
- (
id)initWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age{
    
_name  = name;
    
_gender = gender;
    
_age = age;
    
return self;
}
//self 谁调用该方法,self就代表谁 可用于对象 也可用于类
//测试函数

+ (
void)test{
}
@end
main.m文件
#import  <Foundation/Foundation.h>
#import 
"Person.h"
#import 
“mobilePhone.h" 头文件的导入

int  main( int  argc,  const   char  * argv[])
{
    
@autoreleasepool  {
        
Person  *p = [[ Person   alloc init ]; // 开辟空间   初始化
        [p 
sayHi ]; // 对于对象的方法实现
        [
Person   fight ]; // 对于类的方法实现
        
Person  *xiaoMing = [[ Person   alloc init ]; // 开辟内存 , 并初始化
        [xiaoMing 
setName : @"duke" ]; // 字符串对象   需要 %@ 输出
        [xiaoMing 
setGender : @"female" ];
        [xiaoMing 
setAge : 20 ]; // 就是个简单地变量类型
        [xiaoMing 
sayHi ];
        
Person  *xiaoli = [[ Person   alloc ] initWhitName : @"frank"   gender : @"m"   age : 18 ]; // 调用初始化方法   自定义的
        [xiaoli 
sayHi ];    
    }
    
return   0 ;
}

11 . 继承  
继承的思想:当多个类出现部分相同的实例变量和方法时,就考虑用继承 .
继承的使用:将多各类中相同的实例变量的方法提出来写成一个公共父类.
子类继承父类:会将父类中中除了声明为@private的实例变量以及私有方法之外,其他内容会继承.如果子类中有父类相同的内容,可以全部删除父类继承过来东西就是自己的 不是父类的 相当于拷贝过来一份 可以直接来用
私有方法:在.m中实现,但是没有在.h中声名的方法 不允许外部访问,本类内部可以访问
使用私有方法的方式 [self aa];

12.消息发送机制 [receiver message];  这里receiver可以使类 也可以是对象 如果message是+号方法 这里就是类 如果是- 号方法这里是对象 
13.OC里的id泛指搜友的对象类型 可以用对应的对象类型来接收 
14.创建对象分两步:首先在堆区开辟内存空间,然后对空间对象赋初值 如定义一个Person类 首先[Person alloc];开辟内存空间 然后将变量赋初值操作  Person *per = [[Person allocinitWithName:@"frank" sex:@"man" age:18];
调用方法 [per    sayhi];’[接收者 message];
15.(NSString *)字符串类的对象  输出控制是%@   (NSInteger) 整形变量   输出控制是%ld (CGFloat)浮点型变量 输出控制使用%g 或者 %f  注意区别 
16. self 和super的区别 
  1. self调用自己方法,super调用父类方法
  2. self是类,super是预编译指令
  3. 【self class】和【super class】输出是一样的
  4. self和super底层实现原理:
  1. 当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,则从父类的方法列表中开始找,然后调用父类的这个方法。
  2. 当使用 self 调用时,会使用 objc_msgSend 函数: id objc_msgSend(id theReceiver, SEL theSelector, ...)。第 一个参数是消息接收者,第二个参数是调用的具体类方法的 selector,后面是 selector 方法的可变参数。以 [self setName:] 为例,编译器会替换成调用 objc_msgSend 的函数调用,其中 theReceiver 是 self,theSelector 是 @selector(setName:),这个 selector 是从当前 self 的 class 的方法列表开始找的 setName,当找到后把对应的 selector 传递过去。
  3. 当使用 super 调用时,会使用 objc_msgSendSuper 函数:id objc_msgSendSuper(struct objc_super *super, SEL op, ...)第一个参数是个objc_super的结构体,第二个参数还是类似上面的类方法的selector,

struct objc_super {
      id receiver;
      Class superClass;
};

当编译器遇到  [super setName:] 时,开始做这几个事:
1)构 建 objc_super 的结构体,此时这个结构体的第一个成员变量 receiver 就是 子类,和 self 相同。而第二个成员变量 superClass 就是指父类 调用 objc_msgSendSuper 的方法,将这个结构体和 setName 的 sel 传递过去。
2)函数里面在做的事情类似这样:从 objc_super 结构体指向的 superClass 的方法列表开始找 setName 的 selector,找到后再以 objc_super->receiver 去调用这个 selector
17.方法的声明是在.h文件里,而方法的实现是在.m文件里 .h文件里 以@interface Person :NSObject {实例变量} 行为方法 @end 结束   .m文件里 @implementation Person 开头  方法的实现部分 @end结束 在一个文件里可以定义多个类 只要符合框架就可以 如:
@interface Student : NSObject
{
    
NSString *name;
    
NSString *sex;
}
@end

@interface aa : NSObject
{
    
NSString *name;
    
NSString *sex;
}
@end
//一个文件里可以有很多个类 只要符合 接口文件的声明和实现的框架就可以 和文件名没有关系 一般情况下 一个文件中就定义一个类 类的名字和文件同名

18.setter 和 getter 方法 setter 都没有返回值,但都有参数 参数为实例变量 且只能有一个 给实例变量赋初值  getter 都没有参数 都有返回值 给实例变量获取值 
下面以一个实例来说明setter 和 getter 方法 比如有一个实例变量 int age ;
现在.h文件里声明setter 和 getter 器 
- (void)setAge:(int)newAge;
- (int)age;
在.m文件里具体实现
- (void)setAge:(int)newAge{
age = newAge;

}
- (int)age{
return age;
}
可以看出setter 以set开头 表示设置对象的属性 表示可写 getter方法前面不加get 因为在OC里get还有其他的用途 
调用方法:一般的调用时使用[]比如
Person *person = [[Person alloc]init ];
[person  setAge:13];//利用设置器将age修改成13
int age = [person age];//getter的调用方法 
点调用:person.age = 13;//点调用出现在= 号左边 相当于setter 
int age = person.age;//.号出现在等号的右边相当于getter 
19. 遍历构造器和初始化的区别 
1.初始化: 自定义一个初始化方法 - 标识符 对象方法  + 类方法
- (id)initWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age; 对应的方法名为: - ( )initWhitName: namegender: gender age: age
初始化的实现过程:
- (id)initWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age{
    
self = [super init];//为父类继承实现初始化
    
if (self != nil) {//判断是否初始化成功
        
_name = name;
        
_gender = gender;
        
_age = age;
    }
        
return self
;//返回初始化的对象
}
对于继承有父类的方法时:初始化过程:
//初始化的实现
- (
id)initWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age number:(NSInteger)number score:(NSInteger)score major:(NSString *)major{
    
//先为从父类继承过来的实例变量赋初值
    
self =[super initWhitName:name gender:gender age:age number:number score:score];
    
//再为自己的独有的实例方法赋初值
    
if (self != nil) {
        
_major = major;
    }
    
return self
;
}

2.便利构造器的方法:+  ( id )类名WhitName:( NSString  *)name gender:( NSString  *)gender age:( NSInteger )age; 对应的方法名位:+  ( )initWhitName: namegender: genderage: age 注意: :号也是方法名的一部分 中间不能有空格 
作用: 快速创建对象,内部封装了创建对象的过程
格式 1. + 号方法 2. 返回值为id类型 3.类名+ With拼接上多个参数
便利构造器的实现过程:
+ (
id)studentWhitName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age number:(NSInteger)number score:(NSInteger)score{
//创建该类的对象 创建对象的两步
    
return [[Student allocinitWhitName:name gender:gender age:age number:number score
:score];//这里需要注意使用的是return的方法 类的相关属性
}

遍历构造器属于类方法 初始化方法属于对象方法.

20.类之间的调用和重复调用
比如当定义一些类来描述一个家庭的时候 在家庭的类里要同时调用孩子 父亲 母亲 但在 孩子 父亲 母亲  类里又会调用家庭类 这时候就会出现重复定义的情况 所以为了不免这种情况 我们采用在家庭里的.h文件里用 @class   woman ; @class   man ; @class   Child ; 在.m文件里导入 #import "Child.h"#import "man.h"#import "woman.h"这样就解决了重复导入的情况.
21.继承时导入头文件的原则:继承父类的东西,导入父类的头文件 集成谁就导入谁.
22.  @property   @synthesize

Objective-C语言关键词,与@synthesize配对使用。xcode4.5以及以后的版本,@synthesize可以省略
功能:让编译器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。
如:
1、在头文件中:
@property int count;
等效于在头文件中声明2个方法:
- (int)count;
-(void)setCount:(int)newCount;
2、实现文件(.m)中
@synthesize count; 
其中参数主要分为三类:

 读写属性: (readwrite/readonly)setter语意:(assign/retain/copy)原子性: (atomicity/nonatomic)

 各参数意义如下:

 readwrite: 产生setter\getter方法

readonly: 只产生简单的getter,没有setter。

assign: 默认类型,setter方法直接赋值,而不进行retain操作

retain: setter方法对参数进行release旧值,再retain新值。

copy: setter方法进行Copy操作,与retain一样

nonatomic: 禁止多线程,变量保护,提高性能

23. API文档里的对象的使用函数
1.创建字符串对象的两种方法:
1.   //便利构造器   stringWithFormat :(NSString *), ... 便利产生不可变的字符串对象 加号方法. 传入的是字符串对象 可以带格式串如:%d
        NSString *str1 = [NSString stringWithFormat:@"iPhone%d",5];//加号方法 
2.//alloc + 初始化方法   initWithFormat: (NSString *), …初始化产生的字符串对象 可以带格式串 如%d   NSString *str2 = [[NSString allocinitWithFormat:@"iPhone%d",4];//减号方法 对象 

2.对获取的字符串进行处理:   
1. 获取字符串的长度 length   - (NSUInteger)length 返回字符串的长度  返回值是一个无符号整形的变量 接收用%lu   对象方法
        NSUInteger length = [str1 length];
        NSLog(@"%lu",length);//得到的是肉眼看到的数目.
2.  获取字符串中的字符   characterAtIndex    - (unichar)characterAtIndex:(NSUInteger)index  对象方法   ( NSUInteger ) index 整形下标 返回的时下表对应的字母 返回值利用%C来接收.  注意的是:下表不可越界.
        unichar charac = [str1 characterAtIndex:4];
        NSLog(@"%c",charac);//不能越界
3.判断是否是以某些字符开头 某些字符结束
  NSString  *str4 = [[ NSString   alloc initWithFormat : @"http://www.translate.com" ];
1.以某些字符开头  hasPrefix:<#(NSString *)#> 后面填写的是字符串对象 @“”;返回值是一个bool类型 0或者1
BOOL isPrefix = [str4 hasPrefix:@"http"];
2,.以某些字符结束 hasSuffix:<#(NSString *)#> 后面填写的是字符串对象 @“”;返回值是一个bool类型 0或者1
BOOL  isSuffix = [str4  hasSuffix : @"com ];
3.查找指定字符串的范围  rangeOfString :<#(NSString *)#>   - (NSRange)rangeOfString:(NSString *)aString      NSRange 结构体重新命名得到的   返回值为 :range.location  range.length   只查找有没有   而不管有几个   如果有返回开始下表和长度
        NSRange range/*( NSString  * NSStringFromRange )和前面的等价*/ = [str4  rangeOfString : @"http" ];
        if (range.length == 0) {
            
NSLog(@"没有相关的字符串");
        }
else{
            
//NSRange 结构体类型变量直接转换成字符串对象输出

A structure used to describe a portion of a series—such as characters in a string or objects in an NSArray object.

         /* typedef struct _NSRange {
            NSUInteger location;      
            NSUInteger length;
            } NSRange;
            */

            
NSLog(@"%@",NSStringFromRange(range));   {0,4}返回值
//NSLog(@"locatio = %lu,length = %lu",range.location,range.length);等价于上面的方法
NSString * NSStringFromRange (
   NSRange range);
}
4.   字符串截取  从给定下表到结束  substringFromIndex  substringToIndex substringWithRange 由于操作的是不可变的字符串 这里操作的是副本
        NSString *str5 = [NSString stringWithFormat:@"lanou is a big company"];   //便利构造器的方法 快速产生字符串对象
1.获取给定下标之后的字符串,包含指定下标对应的字符  空格也要算在内 from包含
        
//例如要获取company
        
NSString *subString1 = [str5 substringFromIndex:15];
        
NSLog(@"subString = %@"
,subString1);
2.获取给定下标之前的字符串,不包含指定下标对应的字符 空格也要算在内 to不包含
                  // 如:lanou
        
NSString *subString2 = [str5 substringToIndex:5];
        
NSLog(@"subString = %@"
,subString2);

3.获取制定一个范围的字符串 substringWithRange   Returns a string object containing the characters of the receiver that lie within a given range.
- (NSString *)substringWithRange:(NSRange)aRange
        //例如获取:lanou   利用NSMakeRange(0, 5)
 
NSString *subString3 = [str5 substringWithRange:NSMakeRange(05)];
        
NSLog(@"subString3 = %@",subString3);

4. 字符串拼接  stringByAppendingFormat Returns a string made by appending to the receiver a string constructed from a given format string and the following arguments. 
- (NSString *)stringByAppendingFormat:(NSString *)format...
 stringByAppendingString Returns a new string made by appending a given string to the receiver.
- (NSString *)stringByAppendingString:(NSString *)aString
        NSString *str6 = [NSString stringWithFormat:@"lanou"];
        
//lanou 后拼接 henan
        
NSString *newStr6 = [str6 stringByAppendingString:@"henan"];//不可以出现格式串
        
NSLog(@"newStr6 = %@",newStr6);
        
//lanou 后拼接 henan9ban
        
NSString *newStr7 = [str6 stringByAppendingFormat:@"henan%dban",9];//可以出现格式串
NSLog ( @"newStr7 = %@" ,newStr7);
        NSString *newStr8 = [str6 stringByAppendingFormat:@"%@",newStr7];//特别注意可以拼接对象
        
NSLog(@"newStr8 = %@"
,newStr8);
5.替换字符串 stringByReplacingOccurrencesOfString: withString: Returns a new string in which all occurrences of a target string in the receiver are replaced by another given string.
- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement
        NSString *str8 = [NSString stringWithFormat:@"lan ouououououououou isabigcompany"];
        
//(1)ou替换成nb
        
NSString *newStr9 = [str8 stringByReplacingOccurrencesOfString:@"ou"withString:@"牛逼"]; //换掉谁谁在前 换上谁 谁在前
        
NSLog(@"newStr8 = %@",newStr9);
        
//2.只将第一个ou换成牛逼 如果替换两个 就写两次 牛逼
        
NSString *newStr10 = [str8 stringByReplacingCharactersInRange:NSMakeRange(42withString:@"牛逼"];
        
NSLog(@"%@",newStr10);

6.字符串比较  返回值为 枚举类型

Returns the result of invoking compare:options:range: with no options and the receiver’s full extent as the range.

- (NSComparisonResult)compare:(NSString *)aString
        /**
         *  enum {
         NSOrderedAscending = -1,  //
升序 返回-1
         NSOrderedSame,// 
相同 返回0
         NSOrderedDescending// 
降序 返回1
         };
         typedef NSInteger NSComparisonResult;
         */

        
NSComparisonResult result = [@"111" compare:@"222"];//前一个比后一个小 升序返回 -1
        
NSLog(@"%ld"
,result);


7.将数字转为字符串对象
        
NSString *str12 = [NSString stringWithFormat:@"%f",5.2];//5.2转换为字符串对象
1.字符串大小写转换

8.字符串的大小写转换函数 

1.@" lan ghasgda HGASIDHH JHFWIEFH J  OU " 全部转换成大写   uppercaseString   Returns a uppercased(大写字母印刷 ) representation of the receiver.
- (NSString *)uppercaseString 无参数 有返回值 消息传送机制

        NSString *upperString = [@"lan ghasgda HGASIDHH JHFWIEFH J  OU" uppercaseString];
        
NSLog(@"upperString = %@",upperString);
        
2.@"
lan  SJA Hjknjkjnkdj sdjkjsd OU " 全部转换成小写   lowercaseString  Returns lowercased representation of the receiver.
- (NSString *)lowercaseString  无参数 有返回值 消息传送机制
  NSString  *lowerString = [ @"lan  SJA Hjknjkjnkdj sdjkjsd OU"   lowercaseString ];
        NSLog(@"lowerString = %@",lowerString);
3.@"
lan bdfh bsdjksbajf jksdbfjkwdbfjk  OU " 首转换成大写  capitalizedString  Returns a capitalized(首字母大写的) representation of the receiver.
- (NSString *)capitalizedString  无参数 有返回值 消息传送机制
        NSString *capitilizedString = [@"lan bdfh bsdjksbajf jksdbfjkwdbfjk  OU" capitalizedString];
        
NSLog(@"capitilizedString = %@"
,capitilizedString);
 
常用的可变字符串处理实例方法
NSMutableString   这里需要注意的是该方法的处理方式是在原字符串上直接进行修改

1.– appendFormat:

 //1.在原字符串的基础上拼接Frank  appendFormat 对于字符串的修改都是在字符串基础上修改,所以修改完的字符串内容发生变化 所以不需要返回值
        [str 
appendFormat:@"Frank"];
        
NSLog(@"%@",str);// lanouhenanFrank

Adds to the end of the receiver the characters of a given string.
增加了接收器的端部在给定的字符串的字符
- (void)appendString:( NSString *) aString 
 
 NSMutableString *str = [NSMutableString stringWithFormat:@"lanouhenan”];
[str appendString:@"Frank”];
注:本文中的所有代码需要前后结合来看.
数组的价值:(1)存数多个元素(2)存储元素只能是对象,对象可以是不同类型(3)数组是一个有序的集合(4)数组中的元素可以重复,而且重复的元素可以成为数组元素
NSArray  不可变数组对象

Creating an Array 利用便利构造器方法   

1. arrayWithObjects:

Creates and returns an array containing the objects in the argument list.

创建并返回包含在参数列表中的对象的数组。

+ (instancetype)arrayWithObjects:(id)firstObj,,

2. initWithObjects:

Initializes a newly allocated set with members taken from the specified list of objects.

初始化一个新分配的一套从对象的指定名单中的成员。

- (instancetype)initWithObjects:(id)firstObj
创建数组对象
        //1.使用便利构造器
        
//1.arrayWithObjects 元素与元素之间用逗号间隔  输出格式 (aa,bb,cc)
        
//2.nil结束 nil后面的元素都不会放入数组中
        
NSArray *arr1 = [NSArray arrayWithObjects:@"aa",@"bb",@"5",nil,@"cc"nil];
        
NSLog(@"arr1 = %@",arr1);//arr1 = (aa,bb,5)
        
//2.使用初始化方法
        
NSArray *arr2 = [[NSArray allocinitWithObjects:@"aa",@"bb",@"5",nil,@"cc",nil];
        
NSLog(@"arr2 = %@",arr2);//arr2 = (aa,bb,5)

3. count:

Returns the number of objects currently in the array.

返回当前阵列的对象的数量。

- (NSUInteger)count 
获取元素个数
        
NSUInteger count = [arr2 count];
         
NSLog(@"count = %lu",count); //count = 3;

4. objectAtIndex:通过下标取元素

Returns the object at the specified index of the set.

返回集合的指定索引处的对象。

- (id)objectAtIndex:(NSUInteger)index

5. firstObject:

Returns the first object in the array.

返回的数组中的第一个对象。

- (id)firstObject 

6. lastObject:

Returns the last object in the ordered set.


返回的有序集合的最后一个对象。
- (id)lastObject
根据索引值获取对象
        
//(1)获取制定下标的元素
        
NSString *str = [arr2 objectAtIndex:1];
        
NSLog(@"str = %@",str);//str = bb;
        
//(2)获取数组中第一个元素 //The first object in the array. If the array is empty, returns nil. firstlast方法比objectAtIndex更加安全,当数组元素为空时会返回null,objectAtIndex会造成程序的crash.即数组下标越界.
        
NSString *str1 = [arr2 firstObject];
        
NSLog(@"str1 = %@",str1);//str1 = aa
        
NSString *str2 = [arr2 objectAtIndex:0];
        
NSLog(@"str2 = %@",str2);//str2 = aa
        
//(3)获取数组中最后个元素
        
NSString *str3 = [arr2 lastObject];
        
NSLog(@"str3 = %@",str3);//str3 = 5

7.indexOfObject:通过对象返回下标

Returns the index of the specified object.

返回指定对象的索引。

- (NSUInteger)indexOfObject:(id)object
获取数组对象在数组中的索引值; Returns the lowest index whose corresponding array value is equal to a given object.数组中的元素可以重复,返回的为第一个.
        
NSUInteger index = [arr2 indexOfObject:@"5"];
        
NSLog(@"index = %lu",index);//index = 2

8. containsObject:判断某一个对象是否存在于数组中
Returns a Boolean value that indicates whether a given object is present in the set.
返回一个布尔值,表示给定的对象是否存在于集合中。
- (BOOL)containsObject:(id)anObject
判断是否包含某个对象. Returns a Boolean value that indicates whether a given object is present in the set.//返回值为bool类型.
        
BOOL isExist = [arr2 containsObject:@"aa"];
        
NSLog(@"isExist = %d",isExist);//isExist = 1

9. sortedArrayUsingSelector:

Returns an array that lists the receiving array’s elements in ascending order, as determined by the comparison method specified by a given selector.

- (NSArray *)sortedArrayUsingSelector:(SEL)comparator
数组排序
        
NSArray *sortArr = [arr2 sortedArrayUsingSelector:@selector(compare:)];//这里传入的是比较方法
        
NSLog(@"sortArr = %@", sortArr);

10.forin  

快速遍历(快速枚举)
        
for (int i = 0; i < [arr2 count]; i++) {
            
NSString *str4 = [arr2 objectAtIndex:i];
            
NSLog(@"%@",str4);
        }
        
/*
        for (type *object(
数组元素类型 对象名字) in collection(集合即:要取元素的数组)) {
         statements 
输出语句
         }       forin 
快速遍历,用于将集合中的元素遍历出来.
        */

        
        
for (NSString *str4 in arr2) {
            
NSLog(@"%@",str4);
        }



NSMutableArray  可变的数组对象处理函数
首先创建数组对象,然后针对数组对象进行操作
//创建数组对象
        NSMutableArray *arr1 = [[NSMutableArray alloc] initWithObjects:@"aa",@"bb",@"cc",@"vbvh"@"jd",@"jhsfcu",@"dfdh", nil];

1.addObject:

Inserts a given object at the end of the array.

- (void)addObject:(id)anObject
//1.添加元素
        [arr1 addObject:@"Frank"];
        NSLog(@"arr1 = %@",arr1);

2.insertObject:atIndex:

Inserts a given object into the array's contents at a given index.

- (void)insertObject:(id)anObject atIndex:(NSUInteger)index

//2.插入元素 Duck添加到aa的后面
        [arr1 insertObject:@"Duck" atIndex:1];
        NSLog(@"arr1 = %@",arr1);

3. removeAllObjects

Empties the array of all its elements.

- (void)removeAllObjects

4.removeObjectAtIndex:

Removes the object at index .

- (void)removeObjectAtIndex:(NSUInteger)index
//3.删除元素
        //1.
Duck删除
        [arr1 removeObjectAtIndex:3];
        NSLog(@"arr1 = %@",arr1);
        //2.
删除所有元素

       // [arr1 removeAllObjects];
        // NSLog(@"arr1 = %@",arr1);

5.replaceObjectsInRange:withObjectsFromArray:range:

Replaces the objects in the receiving array specified by one given range with the objects in another array specified by another range.

- (void)replaceObjectsInRange:(NSRange)aRange withObjectsFromArray:(NSArray *)otherArray range:(NSRange)otherRange
//4.替换元素
        //
Frank替换成"shuaige"
        [arr1 replaceObjectAtIndex:6 withObject:@"shuaige"];
        NSLog(@"arr1 = %@",arr1);

6.exchangeObjectAtIndex:withObjectAtIndex:

Exchanges the objects in the array at given indices.

- (void)exchangeObjectAtIndex:(NSUInteger)idx1(下标) withObjectAtIndex:(NSUInteger)idx2(下标)
//5.交换指定的位置
        [arr1 exchangeObjectAtIndex:0 withObjectAtIndex:2];
        NSLog(@"arr1 = %@",arr1);

7.sortUsingSelector:

Sorts the array’s elements in ascending order, as determined by the comparison method specified by a given selector.

- (void)sortUsingSelector:(SEL)comparator
//6.对原数组进行排序  按照ASCII码进行排序
        [arr1 sortUsingSelector:@selector(compare:)];
        NSLog(@"arr1 = %@",arr1);
//7.快速遍历
        for (NSString *str5 in arr1) {
            NSLog(@"%@",str5);
       }
        //
如果数组中元素类型不同,输出时使用统一的泛型 id 可代表所有的对象类型.
        for (id str5 in arr1) {
            NSLog(@"%@",str5);
        }
数值对象 NSNumber

1.numberWithChar:

Creates and returns an NSNumber object containing a given value, treating it as a signed char.

+ (NSNumber *)numberWithChar:(char)value


2.charValue

Returns the receiver’s value as a char.

- (char)charValue 
//将基本数据类型转化成数值对象
//1.定义接本数据类型变量
        
char a = 'f';
        
int b = 20;
        
short c = 100;
        
long d = 1000;
        
float e = 12.345;
        
double f =  10.2222;
        
BOOL isTrue = YES;
//2.将基本数据类型转换成数据对象  全部转换成对应的数值 存储在堆区
        
//相当于中介
        
NSNumber *a1 = [NSNumber numberWithChar:a ];
        
NSNumber *a2 = [NSNumber numberWithInt:b ];
        
NSNumber *a3 = [NSNumber numberWithShort:c ];
        
NSNumber *a4 = [NSNumber numberWithLong:d ];
        
NSNumber *a5 = [NSNumber numberWithFloat:e ];
        
NSNumber *a6 = [NSNumber numberWithDouble:f ];
        
NSNumber *a7 = [NSNumber numberWithBool:isTrue];
        
NSArray *arr = [NSArray arrayWithObjects:a1,a2,a3,a4,a5,a6,a7 ,nil];
        
NSLog(@"%@",arr);//打印数组
//打印数值对象
        
NSLog(@"%@",a1);
        
NSLog(@"%@",a2);
        
NSLog(@"%@",a3);
        
NSLog(@"%@",a4);
        
NSLog(@"%@",a5);
        
NSLog(@"%@",a6);
        
NSLog(@"%@",a7);
//3.NSNumber转换成基本数据
        
char b1 = [a1 charValue];
        
NSLog(@"%c",b1);
        
int b2 = [a2 intValue];
        
NSLog(@"%d",b2);
//4.NSNumber类型数据的比较
        
NSLog(@"%ld",[a1 compare:a2]);//注意对象比较对向
上述具体结果如下:
2014-08-07 18:59:26.555 LessonNnumber[8367:303] (
    102,
    20,
    100,
    1000,
    "12.345",
    "10.2222",
    1
)
2014-08-07 18:59:26.556 LessonNnumber[8367:303] 102
2014-08-07 18:59:26.557 LessonNnumber[8367:303] 20
2014-08-07 18:59:26.557 LessonNnumber[8367:303] 100
2014-08-07 18:59:26.558 LessonNnumber[8367:303] 1000
2014-08-07 18:59:26.558 LessonNnumber[8367:303] 12.345
2014-08-07 18:59:26.558 LessonNnumber[8367:303] 10.2222
2014-08-07 18:59:26.559 LessonNnumber[8367:303] 1
2014-08-07 18:59:26.559 LessonNnumber[8367:303] f
2014-08-07 18:59:26.559 LessonNnumber[8367:303] 20
2014-08-07 18:59:26.560 LessonNnumber[8367:303] 1

24.字典 
1.字典 作用:(1)存储多个数据 (2)用来存储的数据具有一一对应关系(使用key和value来标识) (3)对于字典中的一对键值对叫做字典中的元素,也就一个条目,只要是对象就可以,不做具体的数据类类型的限制4.字典是无序的(字典中关键字key是唯一标示的 一个key只能对应一个value,一个value可以对应多个key)
2.创建不可变字典对象 {元素 ;号间隔}不可变的字典一旦创建就不能修改为只读模式.
1.便利构造器的方法  这里要注意:键值对是成对出现的 到nil结束 
dictionaryWithObjectsAndKeys +号方法 用于创建一个对象 快速创建 Creates and returns a dictionary containing entries constructed from the specified set of values and keys.
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ...
 NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"zhgds",@"name",@20,@"hight",@12,@"age",nil];
        NSLog(@"%@",dic);
2.初始化对象的方法 -号方法 开辟空间 初始化对象 initWithObjectsAndKeys Initializes a newly allocated dictionary with entries constructed from the specified set of values and keys.
- (instancetype)initWithObjectsAndKeys:(id)firstObject, ...

 NSDictionary *dic1 = [[NSDictionary allocinitWithObjectsAndKeys:@"zhgds",@"name",@20,@"hight",@12,@"age",nil];
        
NSLog(@"%@",dic1);

3.求字典中元素的个数  count  Returns the number of entries in the dictionary.
- (NSUInteger)count
 NSLog(@"%lu",[dic count]);
4.获取字典中所有key Returns a new array containing the dictionary’s keys.
- (NSArray *)allKeys 注意返回值为一个数组

NSArray *keys = [dic allKeys];
        NSLog(@"%@",keys); 
5.objectForKey 根据key获取对应的value 根据对象取值 类型一定要匹配
        NSString *name = [dic objectForKey:@"name"];
        
NSLog(@"%@",name);
        
NSNumber *age = [dic objectForKey:@"age"];
        
NSLog(@"%@",age);
        
NSNumber *hight = [dic objectForKey:@"hight"];
        
NSLog(@"%@",hight);
6. 快速遍历 对于数组来说遍历到的是数组中的元素 对于字典来时遍历到的是key 一个key对应一个value value可以对应多个key
        
for (NSString *k in dic) {
            
//检索到key之后获取对应的value.
            
NSLog(@"%@",[dic objectForKey:k]);
        }

7.创建可变字典对象 NSMutableDictionary
1.创建对象的两种方式 便利构造器和初始化
   NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"xiaoguang",@"guanggun1",@"xiaoshuai",@"guanggun2",@"xiaomeng",@"guanggun3", nil];
        NSLog(@"%@",dic);
   NSMutableDictionary * dic1 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"xiaoguang",@"guanggun1",@"xiaoshuai",@"guanggun2",@"xiaomeng",@"guanggun3", nil];
        NSLog(@"%@",dic1);
2.求字典元素个数  同样是 count 返回值是一个整形的数
        NSLog(@"%lu",[dic count]);

3.删除元素 removeObjectForKey removeAllObjects
        [dic removeObjectForKey:@"guanggun1"];
        NSLog(@"%@",dic);
        [dic removeAllObjects];
        NSLog(@"%@",dic);
4.
添加元素 setObject需要特别注意 这里用的是set方法 
        [dic setObject:@"chengjie" forKey:@"guanggun1"];
        NSLog(@"%@",dic);

5.
修改key对应的value
        [dic setObject:@"xiaocun" forKey:@"guanggun1"];
        NSLog(@"%@",dic);
 setObject:forKey:
工作原理:根据指定key查找字典中是否存在相同的,若果存在则修改对应的value ,若果不存在,在字典中添加一个元素key-value键值对.

6.
快速遍历 对于数组来说遍历到的是数组中的元素 对于字典来时遍历到的是key 一个key对应一个value value可以对应多个key
        for (NSString *k in dic) {
            //
检索到key之后获取对应的value.
            NSLog(@"%@",[dic objectForKey:k]);
        }

25.集 集合类 NSSet 不可变集合 
1.创建集合对象 两种方法 便利构造器  初始化方法 输出规范 {(元素,号间隔)} setWithObjects  initWithObjects
 NSSet *set1 = [NSSet  setWithObjects:@"1",@"2",@"3",@"4",@"5",@"6", nil];
        NSLog(@"%@",set1);
 NSSet *set = [[NSSet alloc] initWithObjects:@"1dghdaj",@"2",@"3hsdflds",@"4",@"5",@"6", nil];
        NSLog(@"%@",set);
2.获取元素个数 count
NSLog(@"%lu",[set count]);
3.获取集合的某个元素
NSString *str = [set anyObject];
        NSLog(@"%@",str);
        
        NSString *str1 = [set anyObject];
        NSLog(@"%@",str1);
        
        NSString *str2 = [set anyObject];
        NSLog(@"%@",str2);

        NSString *str3 = [set anyObject];
        NSLog(@"%@",str3);
获取原则 :怎么方便怎么获取 可能是随机 但以上三种输出结果都一样 也不是随机 具体理解请参考API文档
4.判断集合中是否包含某个元素 containsObject
        BOOL isExist = [set containsObject:@"2"];
        NSLog(@"isExist = %d",isExist);

5.可变集合 创建对象两种方式 便利构造器 初始化 
1.便利构造器  setWithObjects
NSMutableSet *set1 = [NSMutableSet  setWithObjects:@"1",@"2",@"3",@"4",@"5",@"6", nil];
        NSLog(@"%@",set1);
2.初始化方法
NSMutableSet *set1 = [[NSMutableSet alloc]  initWithObjects:@"1",@"2",@"3",@"4",@"5",@"6", nil];
        NSLog(@"%@",set1);
2.添加元素到集合中 利用 addObject:添加对象
[set1 addObject:@"6"];
         NSLog(@"%@",set1);

3.移除集合中的对象的方法 removeObject
[set1 removeObject:@"5"];
         NSLog(@"%@",set1);

26.排序高级
针对对象的不同属性的实例方法进行排序
1.main.m文件里
#import <Foundation/Foundation.h>
#import 
"Person.h"
int main(int argc, const char * argv[])
{
    
@autoreleasepool { 
        
//创建四个对象
        
Person *xiaoli = [[Person alloc]initWithName:@"xiaoli" age:18 height:172];
        
Person *zhangsan = [[Person allocinitWithName:@"zhangsan" age:20 height:175];
        
Person *lisi = [[Person allocinitWithName:@"lisi" age:21 height:168];
        
Person *wangwu = [[Person allocinitWithName:@"wangwu" age:24 height:182];
        
//将对象存入数组中.
        
NSArray *arr = [NSArray arrayWithObjects:xiaoli,zhangsan,lisi,wangwu, nil];
        
//sortedArrayUsingSelector适用于升序排序以及系统自定义的类进行排序    
        
//对数组对象按姓名升序排列
        
NSArray *sortArrName =[arr sortedArrayUsingSelector:@selector(compareByName:)];
        
NSLog(@"%@",sortArrName);     
        
//对数组对象按年龄升序排列
        
NSArray *sortarrage = [arr sortedArrayUsingSelector:@selector(compareByAge:)];
        
NSLog(@"%@",sortarrage);
        
//对数组对象按身高升序排列
        
NSArray *sortarrheight = [arr sortedArrayUsingSelector:@selector(compareByHeight:)];
        
NSLog(@"%@",sortarrheight);
        
//对数组对象按姓名降序排列
        
NSArray *sortarrnameDesecending =[arr sortedArrayUsingSelector:@selector(compareByAge:)];
        
NSLog(@"%@",sortarrnameDesecending);       
//对字符串数组进行排序
//block的排序方式适用于数组中的对象是系统类型时 并且是降序排列时
        
NSArray *arr1 = [[NSArray allocinitWithObjects:@"aa",@"bb",@"cc",@"dd",@"ee",@"ff"nil];
        
//1.对数组进行升序排序
        
NSArray *sortArrAscending = [arr1 sortedArrayUsingSelector:@selector(compare:)];
        
NSLog(@"%@",sortArrAscending);
        
//1.对数组进行降序排序
        
NSString *sortArrDescending =[arr1 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
           
//block匿名函数实现,比较方法
           
//id 转为NSString类型
           
NSString *str1 = (NSString *)obj1;
           
NSString *str2 = (NSString *)obj2;
           
//2.字符串比较
           
return -[str1 compare:str2];
       }];
        
NSLog(@"%@",sortArrDescending);
}
    
return 0;
}

Person.h文件里
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    
NSString *_name;// 姓名
    
NSInteger _age;//年龄
    
CGFloat _height;//    
}
//设置名字
- (
void)setName:(NSString *)name;
//访问名字
- (
NSString *)getName;
//设置年龄
- (
void)setAge:(NSInteger)age;
//访问年龄
- (
NSInteger)getAge;
- (
void)setHeight:(CGFloat)height;
- (
CGFloat)getHeight;
//初始化方法
- (
id)description;
//定义初始化方法
- (
id)initWithName:(NSString *)name age:(NSInteger)age height:(CGFloat)height;
//添加比较方法 compare  NSComparisonResult枚举结果
- (
NSComparisonResult)compareByAge:(Person *)anotherPerson;
- (
NSComparisonResult)compareByHeight:(Person *)anotherPerson;
- (
NSComparisonResult)compareByName:(Person *)anotherPerson;
- (
NSComparisonResult)compareByNameDesecending:(Person *)anotherPerson;
@end

Person .m 文件里
#import "Person.h"
@implementation Person
#pragma mark - setter and getter
//设置名字
- (
void)setName:(NSString *)name{
    
_name = name;
}
//访问名字
- (
NSString *)getName{
    
return _name;
}
//设置年龄
- (
void)setAge:(NSInteger)age{
    
_age = age;
}
//访问年龄
- (
NSInteger)getAge{
    
return _age;
}
- (
void)setHeight:(CGFloat)height{
    
_height = height;
}
- (
CGFloat)getHeight{
    return _height;
}
#pragma mark - override method
- (id)description{
    
return [NSString stringWithFormat:@"name:%@,age:%ld,height:%g",_name,_age,_height];
}
#pragma mark - init method
- (id)initWithName:(NSString *)name age:(NSInteger)age height:(CGFloat)height{
    
self = [super init];
    
if (self) {
        
_name = name;
        
_age = age;
        
_height =height;
    }
    
return self;
}
#pragma mark - compare method
//添加比较方法 compare  NSComparisonResult枚举结果
//比较年龄
- (
NSComparisonResult)compareByAge:(Person *)anotherPerson{
    
if ([self getAge] > [anotherPerson getAge]) {
        
return NSOrderedDescending;//对应的是 1
    } 
else if ([self getAge] == [anotherPerson getAge]){
        
return NSOrderedSame;//对应的是 0
    } 
else {
        
return NSOrderedAscending;//对应的是 -1
    }
}
//比较身高
- (
NSComparisonResult)compareByHeight:(Person *)anotherPerson{
    
if ([self getHeight] > [anotherPerson getHeight]) {
        
return NSOrderedDescending;//对应的是 1
    } 
else if ([self getHeight] == [anotherPerson getHeight]){
        
return NSOrderedSame;//对应的是 0
    } 
else {
        
return NSOrderedAscending;//对应的是 -1
    }
}
- (
NSComparisonResult)compareByName:(Person *)anotherPerson{
  
return [[self getNamecompare:[anotherPerson getName]];
}
- (
NSComparisonResult)compareByNameDesecending:(Person *)anotherPerson{
    
return - [[self getNamecompare:[anotherPerson getName]];
}
@end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值