import 指令(将文件的内容在预编译的时候拷贝到写指令的地方)
import <Foundation/Foundation.h>
Foundation 框架
NSLog 函数 NSLog(@"Hello, World!");
NSString
语法: NSString *str = @"jack";
字符串占位符: %@
数据类型
C 语言支持的数据类型
基本数据类型
int double float char
构造类型
数组 结构体 枚举
指针类型
int *p1
空类型
void
typedef 自定义类型
BOOl 类型 YES/NO
Boolean 类型 true/false
class 类
id 类型 万能指针
nil 与 NULL 差不多
SEL 方法选择器
block 代码段
类
类的定义
语法
声明:
@inteface 类名 : NSObject
{
}
@inteface Person : NSObject
{
NSString *_name;
int _age;
float _height;
}
- (void)run;
- (void)run : (参数类型)形参名称;
- (void)run : (参数类型1)形参名称1 : (参数类型2)形参名称2;
- (void)eat : (NSString *)foodName;
- (void)sum : (int)num1 : (int)num2;
@end
实现:
@implementation 类名
@end
实现:
@implementation Person
- (void)run
{
NSLog(@"这是一个方法");
}
- (void)eat: (NSString *)foodName
{
NSLog(@"这是一个方法的参数%@", foodName);
}
- (int)sum : (int)num1 : (int)num2 {
int sum = num1 + num2;
NSLog(@"num1和num2的和是%d", sum);
return sum;
}
@end
实例化
Person *p1 = [Person new];
调用实例方法
[p1 run];
[p1 eat : @"红烧排骨"];
[p1 eat: 1: 2];
方法中访问属性
NULL和nil的区别
NULL一般用于指针不指向内存内存中的任何一块空间
nil一般用于类指针不指向任何对象
类的封装
setter
getter
对象和对象之间的关系(组合/依赖/关联/继承)
static关键字
C语言中的static关键字
a.修饰局部变量
b.修饰全局变量
c.修饰函数
OC中的static关键字
a. static不能修饰属性, 也不能修饰方法
b. static可以修饰方法中的局部变量
如果方法的返回值是当前类的对象, 那么这个方法的返回值写instancetype
self关键字
获取类在代码段中的地址的方式
a. 调试查看对象的isa指针的值
b. 在类方法中查看self的值
c. 调用对象的对象方法class, 就会返回这个对象所属的类在代码中的地址 [person1 class]
d. 调用类的class方法 [Person class]
类的继承
语法(继承所有属性和方法, 包括静态方法和静态属性和类方法):
@inteface Chinese : Person {
}
@end
@implementation Chinese {
}
@end
super关键字
访问修饰符(默认是protected)
@private(只能在对象方法中访问, 子类对象方法无法访问, 无法通过对象访问)
示例
@inteface Chinese : NSObject {
@private
NSString *_name = "Felix";
}
@end
@implementation Chinese {
}
@end
@protected(只能在本类和子类的对象方法中访问, 无法通过对象访问)
@package(只能在当前框架中访问, 了解)
@publick(可以在任何地方访问)
修饰符只能修饰属性, 不能修饰方法;
私有属性
将属性写在implementation中
私有方法
只写实现, 不写声明
子类方式的重写
子类在实现的时候重写即可
description方法(每个类都有一个=description方法, 该方法打印的是对象的地址, 可以重写它来适应自己的需求)
sel对象
点语法(就是调用调用对象的setter或者getter方法)
@property
自动生成setter、getter方法的声明(定义还是要自己写);
@inteface Person : NSObject {
NSString *_name;
int _age;
}
- (void) setName: (NSString *) name;
- (NSString *) name;
@property int age;
// 生成age的setter和getter的声明
// 也就是 - (void) setName: (NSString *) name;
// - (NSString *) name;
@end
@synthesize
自动生成getter/setter方法的实现
语法
@synthesize @property名称;
示例:
@inteface Person : NSObject {
NSString *_name;
int _age;
}
@property int age;
@end
@implementation Person
@synthesize
@end
@property 增强
@inteface Person : NSObject
@property NSString *name;
@end
1) 生成一个私有属性, 类型为NSString, 属性名为_name
2) 生成getter/setter声明
3) 生成getter/setter实现
静态类型和动态类型
静态类型: 一个指针指向的对象是一个本类对象;
动态类型: 一个指针指向的对象不是一个本类对象;
id指针 --> 万能指针类型, 可以指向任意OC对象
id id1 = [Person new];
instancetype 代表方法的返回值是当前这个类的对象
语法
+ (instancetype)person {
return [self person];
}
动态类型检测
intanceResonseToSelector 判断一个类中是否有某个方法
resonseToSelector 判断一个对象中是否有某个方法
Person *p1 = [Person new];
BOOL res = [p1 resonseToSelector:@selector(sayHi)];
isKindOfClass方法(对象方法) 判断指定对象是否为指定类的对象或者子类对象
[s1 isKindOfClass: [Person class]]
isMemberOfClass方法(对象方法) 判断指定对象是否为指定类的对象, 不包括子类
[s1 isMemberOfClass: [Person class]]
isSubClassOfClass方法(类范发给) 判断指定对象是否为指定类的子类的对象
构造方法
重写init方法的规范
1) 必须要先调用父类的init方法, 然后将方法的返回值赋值给slef
2) 调用init方法初始化对象有可能失败, 如果初始化失败, 返回的就是nil
3) 判断父类是否初始化成功, 如果初始化成功, 就初始化当前对象的属性
4) 最后, 返回self的值
@implementation Person
- (instancetype)init {
self = [super init];
if (self != nil) {
}
return slef;
}
@end
带参数的init方法
1) init规范
2) 必须以initWith开头
3) 返回值必须是instancetype
声明
@inteface Person
- (instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
实现
@implementation Person
- (instancetype)initWithName:(NSString *)name andAge:(int)age {
self = [super init];
if (self != nil) {
self.name = name;
self.age = age;
}
return slef;
}
@end
调用
Person *felix = [[Person alloc] initWithName: @"小花" andAge : 18]
内存管理
栈区: 局部变量, 当局部变量的作用域被执行完毕之后, 这个局部变量就会被系统立即回收
堆区:OC对象, C函数申请的动态空间
BSS段: 未初始化的全局变量, 静态变量, 一旦初始化以后就会被回收, 并转存到数据段之中
数据段: 已经初始化的全局变量, 静态变量, 直到程序结束的时候才会被回收
代码段: 代码, 程序结束的时候系统会被自动回收存储在代码段中的数据
引用计数器
1) 每一个对象都有一个属性: retainCount, 叫做引用计数器, 类型是unsigned long, 占据8个字节;
引用计数器的作用, 用来记录当前这个对象有多少个人在用
内存管理的分类
MRC: Manual Reference Counting 手动引用计数, 手动没存管理
ARC: Automatic Reference Counting 自动引用计数, 自动内存管理
重写dealloc的规范
必要要调用父类的dealloc方法, 并且调用父类dealloc的方法必须放在dealloc方法的最后;
@property参数
@property的四组参数(参数顺序可以随意, 但是一般按照如下顺序写)
a. 与多线程相关的两个参数
atomic(多线程安全锁: 安全、效率低下)
nonatomic(不加多线程安全锁: 不安全、效率高)
b. 与生成的setter方法的实现相关的参数
assign: 默认值, 生成的setter方法直接赋值
retain: 生成的setter方法就是标准的MRC的内存管理, 也就是先判断是否为同一个对象, 如果是release旧的, retain新的
当属性类型是OC对象类型的时候, 那么就用retain, 否则用assign
注意: 要手动写重写dealloc方法
c. 与生成只读、读写相关的参数
readonly: 只读, 只会生成getter, 不会生成setter
readwrite: 默认值, 同时生成getter和setter
d. 与生成的getter setter方法名字相关的参数
getter、setter
@property(nonatomic, assign, getter = methodName) age;
@property(nonatomic, assign, setter = methodName:) age;
e. stong、weak 代表指针类型为强类型还是弱类型(默认是强类型)
# 自动释放池
创建自动释放池
@autoreleasepool
{
Person *p1 = [[[Person alloc] init] autorelease];
}
分类
注意事项:
1) 分类中只能写方法, 不能写属性;
2) 在分类中使用@property, 只会自动生成声明, 不能自动生成实现, 也不会自动生成私有属性;
3) 在分类中不能直接访问真私有属性(定义在implementation之中), 但是可以通过getter和setter访问
4) 当分类中有和本类同名的方法的时候, 优先调用分类的方法, 哪怕没有引入分类头文件, 如果多个分类中有相同的方法, 优先调用最后编译的分类的;
延展
1) 延展是一个特殊的分类
2) 延展这个分类没有名字
3) 只有声明, 没有实现, 和本类共享一个实现
4) 分类中只能新增方法, 延展中任意成员都可以写
5) 分类中写@property, 只会生成getter setter的声明
延展中写@property, 会自动生成私有属性, 也会自动生成getter和setter的声明和实现
语法:
@inteface 本类名 ()
- (void)run;
- (void)sleep;
@end
没有实现, 在本类中实现
应用:
为类生成一个私有的@property
延展一般情况下不会独占一个文件, 都是将延展直接写在本类的实现文件中?
OC在C的基础之上新增了一些数据类型
BOOL
Boolean
class
nil
SEL
id(万能指针)
block
block变量
声明:
必须要指定block变量存储的代码是否有参数, 是否有返回值
示例:
返回值类型 (^block变量的名称)(参数列表);
void (^myBlock1)(); 表示声明了一个block类型的变量叫做myBlock1 这个变量只能储存没有返回值没有参数的代码段
int (^myBlock2)(int num1, int num2);
初始化:
代码段的书写格式:
^返回值列表(参数列表) {
代码段;
}
^void () {
NSLog(@"its a");
NSLog(@"its b");
}
myBlock1 = ^void () {
NSLog(@"its a");
NSLog(@"its b");
}
执行:
myBlock1();
使用typedef将复杂的block定义简化
typedef void (^NewType)();
NewType block1;
NewType block2;
typedef int (^NewType)(int num1, int num2);
block访问外部变量
1)在block代码块的内部可以取定义在外部的变量的值, 定义在外部的局部变量和外部变量
2) 在block代码块的内部可以修改全局变量的值, 但是不能修改定义在外部的局部变量的值
3) 如果想要修改定义在block外部的局部变量的值, 需要在局部变量前面加上__block修饰符, 例如__block int num = 300;
protocol协议(声明一大堆方法, 然后类去遵守)
语法: @inteface Person : NSObject <协议1, 协议二>
@required(默认值)、@optional(不实现, 都不会报错, required会报警告⚠️, 但是@optional不会)
协议之间的继承
语法:
@protocol 协议名称 <父协议名称>
@end
限制协议
1) NSObject <StudentProtocol> *指针名 = [Student new];
id <StudentProtocol> id = [Student new];
如果Student队形没有遵守StudentProtocol协议就会报警告
2) 声明一个指针变量, 要求这个指针指向的对象必须遵守多个协议
NSObject <StudentProtocol, SBPtotocol> *stu;
3) 声明一个指定类型的遵守了协议的学生对象
Student <StudentProtocol> *stu;
Foundation框架
字符串常用方法
a. stringWithFormat 字符串拼接
[NSString stringWithFormat: "@大家好, 我叫%@, 我今年%d岁", str, age]
b. lenth 方法, 字符串长度
NSUInteger len = str.length;
c. characterAtIndex
Unichar ch = [str characterAtIndex: 2];
d. isEqualToString 判断两个字符是否相同
e. rangeOfString 搜索某个字符第一次出现的下标(indexOf)
NSRange range = [str rangeOfString];
NSRange是一个NSRange类型的结构体变量
typedef struct _NSRange {
NSUInteger location; 代表子串字主串出现的下标(没有就是unsigned long的最大值)
NSUInteger length; 代表子串创在主创中匹配的长度(没有就是0)
} NSRange;
f. subStringFromIndex 字符创截取
[str subStringFromIndex: 3]; // 从第三个开始截取, 截取到最后
[str subStringToIndex: 3]; // 从第0个开始截取, 截取指定个数
[str subStringWithRange: NSMakeRange(2, 3)]; // 从指定位置开始截取, 截取指定个数
g. stringByReplacingOccurrencesOfString 字符串的替换(相当于replace方法)
NSString *email = @"wasd#qq.com"; // 替换“#”号
email = [email stringByReplacingOccurrencesOfString: @"#", @"@"];
h. NSString *str = @"1" 字符串转其他类型
int num = str.intValue;
int num = str.intValue;
NSInteger num = str.integerValue;
double num = str.doubleValue;
float num = str.floatValue;
long long num = str.longLongValue;
bool num = str.boolValue;
i. stringByTrimmingCharactersInSet 去掉字符串前后空格
[str stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
j. uppercaseString 字符串转大写
[str uppercaseString];
k. lowercaseString 字符串转小写
[str lowercaseString];
创建NSRange变量的方法
1. NSRange range;
range.location = 3;
range.length = 4;
2. NSRange range = { 3, 7 };
3. NSRange range = { .location = 3, .length = 7 };
4. NSRange range = NSMakeRange(3, 7);
NSMutableString
NSMutableString *str = [NSMutableString string];
[str appendString:@"jack"];
[str appendString:@"rose"]; // 追加
[str appendFormat:@"我今年%ds岁了", age]; // 以拼接的方式追加
NSArray
特点:
a. 只能存储OC对象, 任意的OC对象
b. 长度固定, 一旦NSArray数组创建完毕之后, 元素的长度固定, 无法新增, 也无法删除
c. 每个元素都是紧密相连的, 每一个元素仍然有自己的下标
d. 元素的类型是id类型(万能指针)
创建方式:
NSArray *arr = [NSArray arrayWithObejcts: @"rose", @"jack", @"lilei", @"hanmeimei", nil];
简写方式:
NSArray *arr = @[@"rose", @"jack", @"lilei", @"hanmeimei", ]
NSArray常用属性和方法;
NSArray *arr = @[@"jack", @"rose", @"lilei"];
1. 获取数组长度:
NSInteger count = arr.count;
2. 获取指定下标的元素
[arr objectAtIndex: 3];
3. 判断是否包含指定的元素
[arr containsObject: @"lili"];
4. 获取首个, 结尾的元素
arr.firstObject;
arr.lastObject;
5. 查找元素在数组中第一次出现的下标(没有找到就返回NSUInteger的最大值)
NSUInteger index = [arr indexOfObject: @"rose"];
for-in 循环遍历元素语法
for(NSString *str in arr) {
NSLog(@"%@", str);
}
使用block遍历 enumerateObjectsUsingBlock
数组转NSString(js的join方法)
NSArray *arr = @[@"jack", @"rose", @"jim"];
NSString *str = [arr componentsJoinedByString: @"-"];
NSString转数组
NSString = @"柳州市, 城中区, 地王财富中心";
NSArray *arr = [str componentsSeparatedByString: @","];
NSMutableArray(支持动态新增删除功能)
创建:
1. NSMutableArray *arr4 = [NSMutableArray new];
2. NSMutableArray *arr4 = [[NSMutableArray alloc] init];
3. NSMutableArray *arr4 = [NSMutableArray array];
4.NSMutableArray *arr4 = [NSmutableArray arrayWithObjects: @"jack", @"rose", @"lili", nul];
1.新增元素:
NSMutableArray *arr4 = [NSMutableArray new];
[arr4 addObject: @"jack"];
2.新增数组:
NSObject arr = @[@“jack”, @"rose", @"lucy", @"tom"];
NSMutableArray *arr = [NSMutableArray new];
[arr addObjectFromArray: arr];
3.指定下标处插入元素;
NSMutableArray *arr = [NSmutableArray arrayWithObjects: @"jack", @"rose", @"lili", nul];
[arr insertObject: @"lilei" atIndex: 1];
4.删除指定下标的元素:
[arr removeObjectAtIndex: 1];
5.删除所有指定的元素:
[arr removeObject: @"lili"];
6.删除最后一个元素:
[arr removeLastObject];
7.删除所有元素:
[arr removeAllObjects];
NSNumber
NSNumber *number1 = [NSNumber numberWithInt: 10];
NSNumber *number2 = [NSNumber numberWithInt: 20];
NSNumber *number3 = [NSNumber numberWithInt: 30];
NSNumber *number4 = [NSNumber numberWithInt: 40];
NSArray *arr = @[number1, number2, number3, number4]
遍历:
for (NSNumber *num in arr) {
NSLog(@"%D", num.intValue);
}
简写:
NSNumber *number1 = @10;
int num = 10;
NSNumber *n1 = @(num);
NSDictionary
创建方式:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndkeys:@"jack", @"name", @"18", @"age", nil];
简写:
NSDictionary *dict = @{@"name": @"rose", @"age": @"18"};
打印:
NSLog(@"%@", dict);
取值:
dict[name];
dict.count;
[dict obejctForKeys: @"age"];
遍历:
for (id key in dict) {
NSLog(@"%@ = %@", key, dict[key]);
}
使用block遍历 enumerateKeysAndObjectsUsingBlock
NSMutableDictionary
新增key:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndkeys: @"jack", @"name", @"18",@"age", nil];
[dict setObject:@"广州市xx街道", forKey: @"address"];
删除所有的键值对
removeAllObjects
删除指定的键值对
removeObjectForKey
[dict removeObjectForKey: @"age"];
NSFileManager
创建
NSFileManager *manager = [NSFileManager defaultManage];
1. fileExistsAtPath 判断指定路径下的文件是否存在
NSString *path = @"/Users/Apple/deastop/cc.mp3";
BOOL res = [manager fileExistsAtPath: path]
暂停程序sleep
[NSThread sleepForTimeInterval: 10];
CGPoint
声明:
1. CGPoint p1;
p1.x = 20;
p1.y = 30;
2. CGPoint p1 = {20, 30};
3. CGPoint p1 = {.x = 20, .y = 30};
4. CGPiont p1 = CGPointMaker(20, 30);
CGSize
声明:
1. CGSize size;
size.x = 20;
size.y = 30;
2. CGSize size = {20, 30};
3. CGSize size = {.x = 20, .y = 30};
4. CGPiont size = CGSizeMaker(20, 30);
CGRect
CGRect rect;
rect.origin.x = 20;
rect.origin.y = 30;
rect.size.width = 100;
rect.size.height = 200;
NSValue
用来包装结构体, 类似于NSNumber;
字符串和时间相互转换
1. 获取当前系统时间
NSDate *date = [NSDate new];
NSLog(@"%@", date);
2. 时间转字符串
NSDateForMatter *formatter = [NSDateFormatter new];
formatter.dateFormatter = @"yyyy-MM-DD HH:mm:ss";
NSString *str = [formatter stringFromDate: date];
3. 字符串转NSDate对象
NSString *strDate = @“2021年12月12号 12点12分12秒”;
NSDateForMatter *formatter = [NSDateFormatter new];
formatter.dateFormatter = @"yyyy年MM月DD号 HH点mm分ss秒";
NSDate *date = [formatter dateFromString: strDate];
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。