Foundation框架

什么是框架

众多功能\API的集合

 

Foundation框架的作用

Foundation框架是Mac\iOS中其他框架的基础

Foundation框架包含了很多开发中常用的数据类型:

结构体

枚举

 

如何使用Foundation框架

要想使用Foundation框架中的功能,包含它的主文件即可

#import <Foundation/Foundation.h>

 

Foundation框架中的类

Foundation框架提供了非常多好用的类, 比如

NSString : 字符串

NSArray : 数组

NSDictionary : 字典

NSDate : 日期

NSData : 数据

NSNumber : 数字

 

Foundation框架中的类都是以NS为前缀(Next Step的缩写)

乔布斯于1976年创立苹果公司

乔布斯于1985年离开苹果公司, 创立NeXT公司, 开发了Next Step操作系统

在开发Next Step操作系统过程中产生了Foundation框架

1997年, 苹果公司收购NeXT公司, 乔布斯重返苹果公司(Mac系统就是基于Next Step系统)

2007年, 苹果公司发布了iOS系统(iOS系统基于Mac系统)

不小心修改了系统文件

有时候会在不经意之间修改了系统自带的头文件, 比如NSString.h, 这时会出现以下错误:

解决方案很简单, 只需要删除Xcode的缓存即可, 缓存路径是

/Users/用户名/Library/Developer/Xcode/DerivedData

(默认情况下, 这是一个隐藏文件夹)

 

要想看到上述文件夹, 必须在终端敲指令显示隐藏文件夹, 指令如下

显示隐藏文件 : defaults write com.apple.finder AppleShowAllFiles –bool true

隐藏隐藏文件 : defaults write com.apple.finder AppleShowAllFiles –bool false

(输入指令后, 一定要重新启动Finder)

NSString

什么是NSString

一个NSString对象就代表一个字符串(文字内容)

一般称NSString为字符串类

 

右图中的文字内容普遍都是用NSString来表示的

NSString的创建

NSString的创建方式比较多

最直接的方式(这是常量字符串)

NSString *str = @"I'm in itcast.";

 

格式化的方式

NSString *str = [NSString stringWithFormat:@"My age is %d", 10];

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

 

从文件中读取

从URL中读取

从文件中读取

// 用来保存错误信息

NSError *error = nil;

 

// 读取文件内容

NSString *str = [NSString stringWithContentsOfFile:@"/Users/mj/Desktop/test.txt" encoding:NSUTF8StringEncoding error:&error];

 

// 如果有错误信息

if (error) {

    NSLog(@"读取失败, 错误原因是:%@", [error localizedDescription]);

} else { // 如果没有错误信息

    NSLog(@"读取成功, 文件内容是:\n%@", str);

}

从URL中读取

// 用来保存错误信息

NSError *error = nil;

 

// 创建URL路径

NSURL *url = [NSURL URLWithString:@"file:///Users/mj/Desktop/test.txt"];

 

// 读取文件内容

NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];

 

// 如果有错误信息

if (error) {

    NSLog(@"读取失败, 错误原因是:%@", [error localizedDescription]);

} else { // 如果没有错误信息

    NSLog(@"读取成功, 文件内容是:\n%@", str);

}

URL

什么是URL

URL的全称是Uniform Resource Locator(统一资源定位符)

URL是互联网上标准资源的地址

互联网上的每个资源都有一个唯一的URL,它包含的信息指出资源的位置

根据一个URL就能找到唯一的一个资源

 

URL的格式

基本URL包含协议、主机域名(服务器名称\IP地址)、路径

举例: http://ios.itcast.cn/ios/images/content_25.jpg

可以简单认为: URL == 协议头://主机域名/路径

 

常见的URL协议头(URL类型)

http\https :超文本传输协议资源, 网络资源

ftp :文件传输协议

file :本地电脑的文件

URL的创建

传入完整的字符串创建

NSURL *url = [NSURL URLWithString:@"file:///Users/mj/Desktop/str.txt"];

 

通过文件路径创建(默认就是file协议的)

NSURL *url = [NSURL fileURLWithPath:@"/Users/mj/Desktop/str.txt"];

NSString的存储

可以将NSString存储到一个文件中

NSString  *str = @"哇哈哈哈";

[str writeToFile:@"/Users/mj/Desktop/str.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];

 

[str writeToURL:[NSURL URLWithString:@"/Users/mj/Desktop/str.txt"] atomically:YES encoding:NSUTF8StringEncoding error:nil];

NSString的大小写处理

- (NSString *)uppercaseString;

全部字符转为大写字母

 

- (NSString *)lowercaseString

全部字符转为小写字母

 

- (NSString *)capitalizedString

首字母变大写,其他字母都变小写

NSString的比较

- (BOOL)isEqualToString:(NSString *)aString;

两个字符串的内容相同就返回YES, 否则返回NO

 

- (NSComparisonResult)compare:(NSString *)string;

这个方法可以用来比较两个字符串内容的大小

比较方法: 逐个字符地进行比较ASCII值,返回NSComparisonResult作为比较结果

NSComparisonResult是一个枚举,有3个值:

如果左侧   > 右侧,返回NSOrderedDescending,

如果左侧   < 右侧,返回NSOrderedAscending,

如果左侧  == 右侧返回NSOrderedSame

 

- (NSComparisonResult) caseInsensitiveCompare:(NSString *)string;

忽略大小写进行比较,返回值与compare:一致

NSString的搜索

- (BOOL)hasPrefix:(NSString *)aString;

是否以aString开头

 

- (BOOL)hasSuffix:(NSString *)aString;

是否以aString结尾

 

- (NSRange)rangeOfString:(NSString *)aString;

用来检查字符串内容中是否包含了aString

如果包含, 就返回aString的范围

如果不包含, NSRange的location为NSNotFound, length为0

NSRange

NSRange是Foundation框架中比较常用的结构体, 它的定义如下:

typedef struct _NSRange {

    NSUInteger location;

    NSUInteger length;

} NSRange;

// NSUInteger的定义

typedef unsigned int NSUInteger;

 

NSRange用来表示事物的一个范围,通常是字符串里的字符范围或者数组里的元素范围

 

NSRange有2个成员

NSUInteger location : 表示该范围的起始位置

NSUInteger length : 表示该范围内的长度

 

比如@“I love iOS”中的@“iOS”可以用location为7,length为3的范围来表示

NSRange的创建

有3种方式创建一个NSRange变量

方式1

NSRange range;

range.location = 7;

range.length = 3;

 

方式2

NSRange range = {7, 3};

或者 

NSRange range = {.location = 7,.length = 3};

 

方式3 : 使用NSMakeRange函数

NSRange range = NSMakeRange(7, 3);

NSString的截取和替换

- (NSString *)substringFromIndex:(NSUInteger)from;

从指定位置from开始(包括指定位置的字符)到尾部

 

- (NSString *)substringToIndex:(NSUInteger)to;

从字符串的开头一直截取到指定的位置to,但不包括该位置的字符

 

- (NSString *)substringWithRange:(NSRange)range;

按照所给出的NSRange从字符串中截取子串

 

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement;

用replacement替换target

 

NSString与路径

- (BOOL)isAbsolutePath;

是否为绝对路径

 

- (NSString *)lastPathComponent;

获得最后一个目录

 

- (NSString *)stringByDeletingLastPathComponent;

删除最后一个目录    

 

- (NSString *)stringByAppendingPathComponent:(NSString *)str;

在路径的后面拼接一个目录

(也可以使用stringByAppendingString:或者stringByAppendingFormat:拼接字符串内容)

NSString与文件拓展名

- (NSString *)pathExtension;

获得拓展名

 

- (NSString *)stringByDeletingPathExtension;

删除尾部的拓展名

 

- (NSString *)stringByAppendingPathExtension:(NSString *)str;

在尾部添加一个拓展名

NSString的其他用法

- (NSUInteger)length;

返回字符串的长度(有多少个文字)    

 

- (unichar)characterAtIndex:(NSUInteger)index;

返回index位置对应的字符

 

转为基本数据类型

- (double)doubleValue;

- (float)floatValue;

- (int)intValue;

 

- (char *)UTF8String;

转为C语言中的字符串

NSString去除空格

去除所有的空格

[str stringByReplacingOccurrencesOfString:@" " withString:@""]

 

去除首尾的空格

[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

 

NSMutableString

NSMutableString是NSString的子类

 

NSMutableString和NSString的区别

NSString是不可变的,  里面的文字内容是不能进行修改的

NSMutableString是可变的, 里面的文字内容可以随时更改

 

NSMutableString能使用NSString的所有方法

 

NSMutableString的常用方法

- (void)appendString:(NSString *)aString;

拼接aString到最后面

 

- (void)appendFormat:(NSString *)format, ...;

拼接一段格式化字符串到最后面

 

- (void)deleteCharactersInRange:(NSRange)range;

删除range范围内的字符串

 

- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;

在loc这个位置中插入aString

 

- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString;

使用aString替换range范围内的字符串

 

NSArray

什么是NSArray

NSArray是OC中的数组类, 开发中建议尽量使用NSArray替代C语言中的数组

 

C语言中数组的弊端

int array[4] = {10, 89, 27, 76};

只能存放一种类型的数据

不能很方便地动态添加数组元素

不能很方便地动态删除数组元素

 

NSArray的使用注意

只能存放任意OC对象, 并且是有顺序的

不能存储非OC对象, 比如int\float\double\char\enum\struct等

它是不可变的, 一旦初始化完毕后, 它里面的内容就永远是固定的, 不能删除里面的元素, 也不能再往里面添加元素

 

NSArray的创建

NSArray常见的创建方式有

+ (instancetype)array;

+ (instancetype)arrayWithObject:(id)anObject;

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

+ (instancetype)arrayWithArray:(NSArray *)array;

 

+ (id)arrayWithContentsOfFile:(NSString *)path;

+ (id)arrayWithContentsOfURL:(NSURL *)url;

 

可以将一个NSArray保存到文件中

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;

- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically;

 

 

NSArray的检索

- (NSUInteger)count;

获取集合元素个数

 

- (id)objectAtIndex:(NSUInteger)index; 

获得index位置的元素

 

- (BOOL)containsObject:(id)anObject; 

是否包含某一个元素

 

- (id)lastObject; 

返回最后一个元素

 

- (id)firstObject; 

返回最后一个元素

 

NSArray的检索

- (NSUInteger)indexOfObject:(id)anObject;

查找anObject元素在数组中的位置(如果找不到,返回-1)

 

- (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range;

在range范围内查找anObject元素在数组中的位置

 

NSArray的简写

自从2012年开始, Xcode的编译器多了很多自动生成代码的功能, 使得OC代码更加精简

 

数组的创建

之前

[NSArray arrayWithObjects:@"Jack", @"Rose", @"Jim", nil];

 

现在

@[@"Jack", @"Rose", @"Jim"];

 

数组元素的访问

之前

[array objectAtIndex:0];

现在

array[0];

 

NSArray给所有元素发消息

- (void)makeObjectsPerformSelector:(SEL)aSelector;

- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;

让集合里面的所有元素都执行aSelector这个方法

NSArray遍历元素

遍历, 就是将NSArray里面的所有元素一个一个取出来查看

 

常见的遍历方式有

普通遍历

for (int i = 0; i<array.count; i++) {  }

 

快速遍历

for (id obj in array) {  }

 

Block遍历

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

    }];

 

NSArray与NSString

- (NSString *)componentsJoinedByString:(NSString *)separator;

这是NSArray的方法, 用separator作拼接符将数组元素拼接成一个字符串

 

- (NSArray *)componentsSeparatedByString:(NSString *)separator;

这是NSString的方法, 将字符串用separator作为分隔符切割成数组元素

 

 

NSMutableArray

什么是NSMutableArray

NSMutableArray是NSArray的子类

NSArray是不可变的, 一旦初始化完毕后, 它里面的内容就永远是固定的, 不能删除里面的元素, 也不能再往里面添加元素

NSMutableArray是可变的, 随时可以往里面添加\更改\删除元素

NSMutableArray添加元素

- (void)addObject:(id)object;

添加一个元素

 

- (void)addObjectsFromArray:(NSArray *)array;

添加otherArray的全部元素到当前数组中

 

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

在index位置插入一个元素

 

NSMutableArray删除元素

- (void)removeLastObject;

删除最后一个元素

 

- (void)removeAllObjects;

删除所有的元素

 

- (void)removeObjectAtIndex:(NSUInteger)index;

删除index位置的元素

 

- (void)removeObject:(id)object;

删除特定的元素

 

- (void)removeObjectsInRange:(NSRange)range;

删除range范围内的所有元素

 

NSMutableArray替换元素

- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;

用anObject替换index位置对应的元素

 

- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2;

交换idx1和idx2位置的元素

 

NSMutableArray的简写

设置元素

以前

[array replaceObjectAtIndex:0 withObject:@"Jack"];

 

现在

array[0] = @"Jack";

 

NSDictionary

什么是NSDictionary

NSDictionary翻译过来叫做”字典”

日常生活中, “字典”的作用: 通过一个拼音或者汉字, 就能找到对应的详细解释

NSDictionary的作用类似: 通过一个key, 就能找到对应的value

NSDictionary是不可变的, 一旦初始化完毕, 里面的内容就无法修改

 

NSDictionary的创建

+ (instancetype)dictionary;

+ (instancetype)dictionaryWithObject:(id)object forKey:(id <NSCopying>)key;

+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ...;

+ (id)dictionaryWithContentsOfFile:(NSString *)path;

+ (id)dictionaryWithContentsOfURL:(NSURL *)url;

 

NSDictionary的常见使用

- (NSUInteger)count;     

返回字典的键值对数目

 

- (id)objectForKey:(id)aKey;

根据key取出value

 

将字典写入文件中

- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;

- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically;

 

NSDictionary的遍历

快速遍历

for (NSString *key in dict) { }

 

Block遍历

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

    

}];

 

NSDictionary的简写

NSDictionary的创建

以前

[NSDictionary dictionaryWithObjectsAndKeys:@"Jack", @"name", @"男", @"sex", nil];

 

现在

@{@"name": @"Jack", @"sex" : @"男”};

 

NSDictionary获取元素

以前

[dict objectForKey:@"name”];

 

现在

dict[@"name”];

 

NSMutableDictionary

什么是NSMutableDictionary

NSMutableDictionary是NSDictionary的子类

NSDictionary是不可变的, 一旦初始化完毕后, 它里面的内容就永远是固定的, 不能删除里面的元素, 也不能再往里面添加元素

NSMutableDictionary是可变的, 随时可以往里面添加\更改\删除元素

 

NSMutableDictionary的常见操作

- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;

添加一个键值对(会把aKey之前对应的值给替换掉)

 

- (void)removeObjectForKey:(id)aKey;

通过aKey删除对应的value

 

- (void)removeAllObjects;

删除所有的键值对

 

NSMutableDictionary的简写

设置键值对

以前

[dict setObject:@"Jack" forKey:@"name”];

 

现在

dict[@"name"] = @"Jack";

 

 

NSFileManager

什么是NSFileManager

顾名思义, NSFileManager是用来管理文件系统的

它可以用来进行常见的文件\文件夹操作

 

NSFileManager使用了单例模式

 

使用defaultManager方法可以获得那个单例对象

[NSFileManager defaultManager]

NSFileManager的常见判断

- (BOOL)fileExistsAtPath:(NSString *)path;

path这个文件\文件夹是否存在

 

- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;

path这个文件\文件夹是否存在, isDirectory代表是否为文件夹

 

- (BOOL)isReadableFileAtPath:(NSString *)path;

path这个文件\文件夹是否可读

 

- (BOOL)isWritableFileAtPath:(NSString *)path;

path这个文件\文件夹是否可写

 

- (BOOL)isDeletableFileAtPath:(NSString *)path;

path这个文件\文件夹是否可删除

 

NSFileManager的文件访问

- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error;

获得path这个文件\文件夹的属性

 

- (NSArray *)subpathsAtPath:(NSString *)path;

- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;

获得path的所有子路径

 

- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;

获得path的当前子路径

 

- (NSData *)contentsAtPath:(NSString *)path;

获得文件内容

 

NSFileManager的文件操作

- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;

拷贝

 

- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;

移动(剪切)

 

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;

删除

 

NSFileManager的文件操作

- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error;

创建文件夹(createIntermediates为YES代表自动创建中间的文件夹)

 

- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;

创建文件

(NSData是用来存储二进制字节数据的)

 

 

文件下载的简单思路

2.服务器发出响应,返回文件数据

 

3.手机客户端利用NSData来存放

服务器返回的文件数据

 

4.利用NSFileManager将NSData

里面的文件数据写到新的文件中

 

NSPoint\CGPoint

CGPoint和NSPoint是同义的

typedef CGPoint NSPoint;

 

CGPoint的定义

struct CGPoint {

  CGFloat x;

  CGFloat y;

};

typedef struct CGPoint CGPoint;

typedef double CGFloat;

 

CGPoint代表的是二维平面中的一个点

可以使用CGPointMake和NSMakePoint函数创建CGPoint

 

NSSize\CGSize

CGSize和NSSize是同义的

typedef CGSize NSSize;

 

CGSize的定义

struct CGSize {

  CGFloat width;

  CGFloat height;

};

typedef struct CGSize CGSize;

 

CGSize代表的是二维平面中的某个物体的尺寸(宽度和高度)

可以使用CGSizeMake和NSMakeSize函数创建CGSize

NSRect\CGRect

CGRect和NSRect是同义的

typedef CGRect NSRect;

 

CGRect的定义

struct CGRect {

  CGPoint origin;

  CGSize size;

};

typedef struct CGRect CGRect;

 

CGRect代表的是二维平面中的某个物体的位置和尺寸

可以使用CGRectMake和NSMakeRect函数创建CGRect

 

NSNumber

NSArray\NSDictionary中只能存放OC对象, 不能存放int\float\double等基本数据类

如果真想把基本数据(比如int)放进数组或字典中, 需要先将基本数据类型包装成OC对象

NSNumber的创建

以前

+ (NSNumber *)numberWithInt:(int)value;

+ (NSNumber *)numberWithDouble:(double)value;

+ (NSNumber *)numberWithBool:(BOOL)value;

 

现在

@10;

@10.5;

@YES;

@(num);

NSNumber的常用方法

从NSNumber中取出之前包装的基本数据类型

- (char)charValue;

- (int)intValue;

- (long)longValue;

- (double)doubleValue;

- (BOOL)boolValue;

- (NSString *)stringValue;

 

- (NSComparisonResult)compare:(NSNumber *)otherNumber;

- (BOOL)isEqualToNumber:(NSNumber *)number;

NSValue

NSNumber是NSValue的子类, 但NSNumber只能包装数字类型

 

NSValue可以包装任意值

 

因此, 可以用NSValue将结构体包装后, 加入NSArray\NSDictionary中

常见结构体的包装

为了方便 结构体 和 NSValue 的转换, Foundation提供了以下方法

将结构体包装成NSValue对象

+ (NSValue *)valueWithPoint:(NSPoint)point;

+ (NSValue *)valueWithSize:(NSSize)size;

+ (NSValue *)valueWithRect:(NSRect)rect;

 

从NSValue对象取出之前包装的结构体

- (NSPoint)pointValue;

- (NSSize)sizeValue;

- (NSRect)rectValue;

 

 

任意数据的包装

NSValue提供了下列方法来包装任意数据

+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;

value参数 : 所包装数据的地址

type参数 : 用来描述这个数据类型的字符串, 用@encode指令来生成

 

从NSValue中取出所包装的数据

- (void)getValue:(void *)value;

 

NSDate

NSDate可以用来表示时间, 可以进行一些常见的日期\时间处理

 

一个NSDate对象就代表一个时间

 

[NSDate date]返回的就是当前时间

 

NSDate日期格式化

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";

 

// 将NSString转换为NSDate

NSDate *date = [formatter dateFromString:@"2010-03-24 00:00:00"];

 

// 将NSDate转换为NSString

NSLog(@"%@", [formatter stringFromDate:date]);

 

NSCalendar

结合NSCalendar和NSDate能做更多的日期\时间处理

 

获得NSCalendar对象

NSCalendar *calendar = [NSCalendar currentCalendar];

 

获得年月日

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)date;

 

比较两个日期的差距

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;

 

 

NSObject

NSObject可以是所有类的基类, 内部定义了很多常用的方法

- (BOOL)isKindOfClass:(Class)aClass;

判断是否为aClass或者aClass的子类的实例

 

- (BOOL)isMemberOfClass:(Class)aClass

判断是否为aClass的实例(不包括aClass的子类)

 

- (BOOL)conformsToProtocol:(Protocol *)aProtocol

判断对象是否实现了aProtocol协议

 

- (BOOL)respondsToSelector:(SEL)aSelector

判断对象是否拥有参数提供的方法

 

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

延迟调用参数提供的方法,方法所需参数用withObject传入

 

NSString的其他使用场合

通过类名的字符串形式实例化对象

Class class = NSClassFromString(@"Student");

Student *stu = [[class alloc] init];

 

将类名变成字符串

Class class = [Student class];

NSString *className = NSStringFromClass(class);

 

通过方法的字符串形式实例化方法

SEL selector = NSSelectorFromString(@"setName:");

[stu performSelector:selector withObject:@"Mike"];

 

将方法变成字符串

NSStringFromSelector(@selector(setName:));

集合的内存管理

集合,就是能用来容纳OC对象的容器

NSArray、NSDictionary等都是

 

集合有一些内存管理细节

只要将一个对象添加到集合中,这个对象计数器就会 + 1(做一次retain操作)

只要将一个对象从集合中移除,这个对象计数器就会 - 1(做一次release操作)

如果集合被销毁了,集合里面的所有对象计数器都会 - 1(做一次release操作)

 

 

转载于:https://my.oschina.net/itcastBlogs/blog/649726

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值