(一)OC 概述
- OC:基本上所有关键字都是以@开头;
- 编译流程:.m源文件 --> 编译生成 .o目标文件--> 链接成 a.out可执行文件
cc -c main.m --> cc main.o -framework Foundation --> ./a.out
(说明:由于.m文件用到的Foundation框架,所以需要添加参数 -framework Foundation)
// Foundation:框架
// Foundation.h:Foundation框架的主头文件(主头文件包含整个框架的功能)
// #import 可以自动防止文件的内容被重复拷贝
#import <Foundation/Foundation.h>
//#import <Foundation/NSObjCRuntime.h>
// 自定义的头文件使用"",系统的头文件使用<>
#import "two.h"
int main() {// int argc, const char * argv[]
// @autoreleasepool {
// NSLog: 输出内容会 带上时间 并自动换行
NSLog(@"Hello iOS!");
int age = 18;
BOOL b = YES;
//头文件路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h
//输出:age is 18,b is 1
NSLog(@"age is %i,b is %i",age,b);
test1();
// printf("HAHA");
// }
return 0;
}
第二个文件:two.m
#import <Foundation/Foundation.h>
void test1(){
NSLog(@"test1函数被调用!");
}
由于main.h使用了two.m中的函数,所以这里需要声明头文件 two.h
void test1();
合并目标文件: cc main.o two.o
编译:cc -c main.m
cc -c two.m
链接:cc main.o two.o -framework Foundation
执行:./a.out
(二)OC 调用 C
main.m
#import "two.h"
int main() {
// 在OC中调用C函数test1()
test1();
return 0;
}
two.c
#include<stdio.h>
void test1()
{
printf("test1函数被调用\n");
}
two.h
void test1();
编译&链接:cc main.m two.c
执行:./a.out
(三)BOOL 类型
BOOL 本质上是char:typedef signed char BOOL;
它有2种取值:YES/NO;
#define YES (BOOL)1
#define NO (BOOL)0
// BOOL 输出当整型来用
BOOL b = YES;
// BOOL b = 1;
(四)常用结构体
Foundation 框架自带的常用结构体(非 oc 对象):
- NSRange 范围
// NSRange r1 = NSMakeRange(2, 4);
// location:表示目标字符串的起始位置(类似java中的 index),length为目标字符串长度。
// 查找某个字符串在str中的范围(找不到则length=0,location=NSNotFound=-1)
NSRange range = [@"i have a book." rangeOfString:@"ve a "];
if (range.length > 0) {
NSLog(@"location=%ld,length=%ld",range.location,range.length);
}
- NSPoint 坐标点
NSPoint p1 = CGPointMake(10.0, 20.0);
NSLog(@"(x=%f,y=%f)",p1.x,p1.y);
- NSSize 长宽
NSSize s1 = CGSizeMake(10.0, 20.0);
NSLog(@"(width=%f,height=%f)",s1.width,s1.height);
- NSRect 矩形(等价于 NSPoint + NSSize)
// x,y,width,height
NSRect r1 = CGRectMake(0.0, 0.0, 10.0, 20.0);
// 方便打印 NSRect 结构体的所有数据
NSString *str = NSStringFromRect(r1);
NSLog(@"r1=%@",str);
// 反转:字符串转成 NSRect
NSRect r2 = NSRectFromString(str);
NSLog(@"{%f,%f},{%f,%f}", r2.origin.x,r2.origin.y,r2.size.width,r2.size.height);
// 等价于
NSString *s1 = @"{{0, 0}, {10, 20}}"// {0,0}等价于 CGPointZero
NSRect r2 = NSRectFromString(s1);
- CGPointEqualToPoint 判断坐标点是否一致
BOOL b = CGPointEqualToPoint(CGPointMake(1, 1), CGPointMake(1, 1));
NSLog(@"b=%d",b);// 1
- CGRectContainsPoint 判断点是否在矩形内部
BOOL b1 = CGRectContainsPoint(CGRectMake(10.0, 20.0, 100.0, 200.0), CGPointMake(50.0, 60.0));
NSLog(@"b1=%d",b1);// 1
(五)常用类
Foundation 框架自带的常用类:
NSString & NSMutableString 字符串
1.1 NSString 不可变字符串
// C 字符串 ----> OC 字符串
NSString *s1 = [[NSString alloc] initWithUTF8String:"CloudKK"];
// OC 字符串 ----> C 字符串
const char *s2 = [s1 UTF8String];
// 读取文件内容
NSString *s3 = [[NSString alloc] initWithContentsOfFile:@"/Users/xxx/Desktop/1.txt" encoding:NSUTF8StringEncoding error:nil];
NSLog(@"\n%@",s3);
// 协议头://路径
// file:// 访问本地文件资源
// NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/xxx/Desktop/1.txt"];
// 读取文件内容(推荐写法)
// NSURL *url = [NSURL fileURLWithPath:@"/Users/xxx/Desktop/1.txt"];
// 读取网页资源
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/"];
NSString *s4 = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSLog(@"\n%@",s4);
// 写入文件内容
// atomically:YES 表示写入失败后,文件不会创建
BOOL success = [@"CloudKK" writeToFile:@"/Users/xxx/Desktop/2.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"success=%d",success);
1.2 NSMutableString 可变字符串
NSMutableString *s1 = [NSMutableString stringWithFormat:@"age is 20"];
// 追加字符串
[s1 appendString:@" weight is 120.0"];
NSLog(@"s1=%@",s1);
// 删除"is"字符串
[s1 deleteCharactersInRange:[s1 rangeOfString:@"is"]];
[s1 deleteCharactersInRange:NSMakeRange(4, 2)];
// 删除从第4+1 位置开始的2个字符
NSLog(@"s1=%@",s1);
示例:统计项目中所有文件的代码行数
#import <Foundation/Foundation.h>
/// 读取所有代码文件的行数
/// @param filePath 文件全路径(可能是文件,也可能是文件夹)
/// @return 代码行数
NSUInteger countProjectCodeLines(NSString *filePath) {
// 获取 FileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
// 判断是否为文件夹
BOOL isDirectory = NO;
// 返回文件路径是否存在
BOOL fileExistsAtPath = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
if (!fileExistsAtPath) {
NSLog(@"filePath is not exists!");
return 0;
}
if (isDirectory) {// 如果是文件夹
NSLog(@"文件夹:%@",filePath);
// 遍历文件中所有文件
NSArray *array = [fileManager contentsOfDirectoryAtPath:filePath error:nil];
int count = 0;
for (NSString *fileName in array) {
// 拿到文件全路径
NSMutableString *fileDir = [NSMutableString stringWithFormat:@"%@/%@",filePath,fileName];
count += countProjectCodeLines(fileDir);
}
return count;
} else {// 如果是文件,则直接读取
// 1. 先过滤
NSString *extension = [filePath pathExtension];
// 文件后缀 忽略大小写
if (![extension caseInsensitiveCompare:@"m"]
&& ![extension caseInsensitiveCompare:@"h"]
&& ![extension caseInsensitiveCompare:@"c"] ) {
return 0;
}
// 2. 再读取(这里还可以把空行去掉)
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSString *content = [NSString stringWithContentsOfURL:fileUrl encoding:NSUTF8StringEncoding error:nil];
// 将读取到的文件内容分割为每一行
NSArray *array = [content componentsSeparatedByString:@"\n"];
NSUInteger count = array.count;
// 打印文件名及其行数
NSLog(@"%@-%ld",filePath.lastPathComponent,count);
return count;
}
}
int main(int argc, const char * argv[]) {
NSUInteger count = countProjectCodeLines(@"/Users/hamc/Work/Xcode/OC-16/OC-16");
NSLog(@"count=%ld",count);
return 0;
}
NSArray & NSMutableArray 数组(相当于 java 中的 List)
2.1 NSArray 集合类(有顺序) -- 不可变数组(任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
Person *p = [[Person alloc] init];
p.age = 20;
p.name = @"CloudKK";
NSArray *array2 = @[p,@"Haha",@"Hi"]; // 推荐
// NSArray *array = [NSArray arrayWithObjects:p,@"Haha", nil];
// 带下标遍历
for (int i = 0; i < array2.count; i++) {
NSLog(@"array[%d]=%@",i,array2[i]);
}
// 不带下标遍历(类似 kotlin)
for(id obj in array2) {
// int index = [array2 indexOfObject:obj];
NSLog(@"%@",obj);
}
// 使用 block 遍历
[array2 enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// 每次遍历,都会调用block
// idx:index
// obj:对象元素
NSLog(@"%ld----%@",idx,obj);
if (idx == 1) {
// stop = YES后,会停止遍历
*stop = YES;// 注意 stop 是个指针
}
}];
2.2 NSMutableArray 集合类(有顺序) -- 可变数组(任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
Person *p = [[Person alloc] init];
// 创建可变数组
NSMutableArray *array = [NSMutableArray array];
// 添加元素
[array addObject:p];
[array addObject:@"Ha"];
// 删除元素
// [array removeObject:p];
// 清空元素
// [array removeAllObjects];
// 删除下标为0的元素
// [array removeObjectAtIndex:0];
// 添加数组
NSArray *a1 = @[p,@"QWE"];
[array addObjectsFromArray:a1];
// [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// NSLog(@"obj=%@",obj);
// }];
for (id obj in array) {
NSLog(@"obj=%@",obj);
}
// 打印元素个数:4
NSLog(@"count=%ld",array.count);
return 0;
}
NSSet & NSMutableSet 集合 (相当于 java 中的 set)
3.1 NSSet 集合类(无序) -- 不可变集合 (任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSSet *set = [NSSet set];
NSSet *set2 = [NSSet setWithObjects:@"CloudKK", @"HA",nil];
NSLog(@"set2.count=%ld",set2.count);
// 随机拿出一个元素
id str = [set2 anyObject];
NSLog(@"%@",str);
return 0;
}
3.2 NSMutableSet 集合类(无序) -- 可变集合(任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSMutableSet *set = [NSMutableSet set];
// 添加元素
[set addObject:@"CoudKK"];
[set addObject:@"HA"];
// 删除元素
// [set removeObject:@"HA"];
// 清空元素
// [set removeAllObjects];
for (id obj in set) {
NSLog(@"obj=%@",obj);
}
NSLog(@"count=%ld",set.count);
return 0;
}
NSDictionary 字典(相当于 java 中的 map,一个萝卜一个坑 )
4.1 NSDictionary(无序) -- 不可变字典(任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// 方式1:
// NSDictionary *dictionary = [NSDictionary dictionaryWithObject:@"CloudKK" forKey:@"name"];
// 通过 key 拿到value
// id obj = [dictionary objectForKey:@"name"];
// NSLog(@"obj=%@",obj);
// 方式2:(keys,values)
NSArray *keys = @[@"name",@"address"];
NSArray *values = @[@"CloudKK",@"guangdong"];
NSDictionary *d1 = [NSDictionary dictionaryWithObjects:keys forKeys:values];
[d1 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"key=%@,value=%@",key,obj);
}];
// 方式3:(可读取性差 value1,key1,value2,key2,...)
NSDictionary *d2 = [NSDictionary dictionaryWithObjectsAndKeys:
@"CloudKK",@"name",
@"guangdong",@"address", nil];
[d2 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"key=%@,value=%@",key,obj);
}];
// 方式4(推荐写法):(key1:value1,key2:value2,...)
NSDictionary *d3 = @{@"name":@"CloudKK",@"address":@"guangdong"};
[d3 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"key=%@,value=%@",key,obj);
}];
// 取值
id obj = d3[@"name"];
NSLog(@"%@",obj);
NSLog(@"count=%ld",d3.count);
return 0;
}
4.2 NSMutableDictionary(无序) -- 可变字典(任何oc对象都可存放,但不可存放非 oc 对象类型和 nil 值)
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:@"CloudKK" forKey:@"name"];
[dictionary setObject:@"广东" forKey:@"address"];
// 会覆盖 value
[dictionary setObject:@"CloudKK2" forKey:@"name"];
// 清空元素
// [dictionary removeAllObjects];
NSString *str = dictionary[@"name"];
NSLog(@"str=%@",str);
// {
// address = "\U5e7f\U4e1c";
// name = CloudKK2;
// }
NSLog(@"\n%@",dictionary);
return 0;
}
(五)NSNumber(装箱 & 拆箱)是 NSValue 的子类
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// NSDictionary *dict = @{
// @"name":@"CloudKK",
// // 将基本数据类型进行包装成 oc 对象(类似 java 中的装箱)
// @"age":[NSNumber numberWithInt:20],
// @"weight":[NSNumber numberWithDouble:120.0]
// };
// 方式2:使用 @ 装箱
// @20 包装成 NSNumber
NSDictionary *dict = @{
@"name":@"CloudKK",
@"age":@20,
@"weight":@120.0,
// 注意@'A' 是一个 NSNumber 类型
@"score":@'A'
};
NSNumber *age = dict[@"age"];
// 取值(类似 java 中的拆箱)
// age=20
NSLog(@"age=%d",[age intValue]);
NSNumber *score = dict[@"score"];
// score=A
NSLog(@"score=%c",[score charValue]);
// test...
int number = 100;
// 装箱
NSNumber *num = @(number);
// 拆箱
NSLog(@"number=%d",[num intValue]);
return 0;
}
NSValue
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSPoint p = CGPointMake(10, 10);
// 将结构体 NSPoint 转换为 NSValue 对象
NSValue *value = [NSValue valueWithPoint:p];
// 将对象 NSValue 转换为 NSPoint 结构体
NSPoint p1 = value.pointValue;
// 将 NSValue 转换成 NSArray 对象
NSArray *array = @[value];
return 0;
}
(六)NSDate
- NSDate 转 字符串
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// NSDate *date = [NSDate date];
// 默认打印0时区
// NSLog(@"%@",date);
//
// // typedef double NSTimeInterval;
// NSDate *date1 = [NSDate dateWithTimeInterval:5 sinceDate:date];
// NSLog(@"%@",date1);
// // 从1970 开始走过的秒数
// NSTimeInterval date2 = [date1 timeIntervalSince1970];
// NSLog(@"%f",date2);
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 24 小时制
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
// 12 小时制
// formatter.dateFormat = @"yyyy-MM-dd hh:mm:ss";
NSString *str = [formatter stringFromDate:[NSDate date]];
// str=2022-12-18 01:33:19
NSLog(@"str=%@",str);
return 0;
}
- 字符串 转 NSDate
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// NSDate *date = [NSDate date];
// NSLog(@"%@",date);
//
// // typedef double NSTimeInterval;
// NSDate *date1 = [NSDate dateWithTimeInterval:5 sinceDate:date];
// NSLog(@"%@",date1);
// // 从1970 开始走过的秒数
// NSTimeInterval date2 = [date1 timeIntervalSince1970];
// NSLog(@"%f",date2);
NSString *time = @"2022/12/18 12:58";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy/MM/dd HH:mm";
NSDate *date = [formatter dateFromString:time];
NSLog(@"date=%@",date);
return 0;
}
网友评论