-
Notifications
You must be signed in to change notification settings - Fork 0
1. oc的一些比较碎的点
Hannah0103 edited this page Dec 22, 2025
·
8 revisions
浅拷贝:只拷贝对象本身,内容共享;深拷贝:创建新对象,内容独立
| 拷贝方式 | 非容器-不可变对象 | 非容器-可变对象 | 容器-不可变对象 | 容器-可变对象 |
|---|---|---|---|---|
| copy | 浅拷贝-不可变 | 深拷贝-不可变 | 浅拷贝-不可变 | 深拷贝-不可变 |
| mutableCopy | 深拷贝-可变 | 深拷贝-可变 | 深拷贝-可变 | 深拷贝-可变 |
- copy和mutableCopy是foundation框架下的两种拷贝方式;
- copy:返回一个不可变对象
- mutableCopy:返回一个可变对象
-
非容器对象 不可变:NSString、NSNumber 等 可变:NSMutableString、NSMutableData 等
-
容器对象 不可变:NSArray、NSDictionary、NSSet 等 可变:NSMutableArray、NSMutableDictionary、NSMutableSet 等
1、局部变量截获 是值截获。 比如:
NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
return n*num;
};
num = 1;
NSLog(@"%zd",block(2));
这里的输出是6而不是2,原因就是对局部变量num的截获是值截获。 同样,在block里如果修改变量num,也是无效的,甚至编译器会报错。
2、局部静态变量截获 是指针截获。
static NSInteger num = 3;
NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
return n*num;
};
num = 1;
NSLog(@"%zd",block(2));
输出为2,意味着num = 1这里的修改num值是有效的,即是指针截获。 同样,在block里去修改变量m,也是有效的。
3、全局变量,静态全局变量截获:不截获,直接取值。
我们同样用clang编译看下结果。
static NSInteger num3 = 300;
NSInteger num4 = 3000;
- (void)blockTest
{
NSInteger num = 30;
static NSInteger num2 = 3;
__block NSInteger num5 = 30000;
void(^block)(void) = ^{
NSLog(@"%zd",num);//局部变量
NSLog(@"%zd",num2);//静态变量
NSLog(@"%zd",num3);//全局变量
NSLog(@"%zd",num4);//全局静态变量
NSLog(@"%zd",num5);//__block修饰变量
};
block();
}
编译后
struct __WYTest__blockTest_block_impl_0 {
struct __block_impl impl;
struct __WYTest__blockTest_block_desc_0* Desc;
NSInteger num;//局部变量
NSInteger *num2;//静态变量
__Block_byref_num5_0 *num5; // by ref//__block修饰变量
__WYTest__blockTest_block_impl_0(void *fp, struct __WYTest__blockTest_block_desc_0 *desc, NSInteger _num, NSInteger *_num2, __Block_byref_num5_0 *_num5, int flags=0) : num(_num), num2(_num2), num5(_num5->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
( impl.isa = &_NSConcreteStackBlock;这里注意到这一句,即说明该block是栈block) 可以看到局部变量被编译成值形式,而静态变量被编成指针形式,全局变量并未截获。而__block修饰的变量也是以指针形式截获的,并且生成了一个新的结构体对象:
struct __Block_byref_num5_0 {
void *__isa;
__Block_byref_num5_0 *__forwarding;
int __flags;
int __size;
NSInteger num5;
};
该对象有个属性:num5,即我们用__block修饰的变量。 这里__forwarding是指向自身的(栈block)。 一般情况下,如果我们要对block截获的局部变量进行赋值操作需添加__block 修饰符,而对全局变量,静态变量是不需要添加__block修饰符的。 另外,block里访问self或成员变量都会去截获self。
// -- NSString 不可变字符串
// 创建字符串
NSString *str1 = @"Hello World";
NSString *str2 = [[NSString alloc] initWithString:str1];
NSString *str3 = [[NSString alloc] initWithFormat:@"str3 with str1 %@", str1];
NSString *str4 = [NSString stringWithString:str1];
NSLog(@"str1:%@, str2:%@, str3:%@, str4:%@", str1, str2, str3, str4);
// 获取字符串长度
NSUInteger length = [str1 length];
NSLog(@"Length: %lu", (unsigned long)length); // 11
// 拼接字符串
NSString *newStr = [str1 stringByAppendingString:@" Goodbye"];
NSLog(@"%@", newStr); // Hello World Goodbye
// 替换字符串
NSString *replacedStr = [str1 stringByReplacingOccurrencesOfString:@"Hello" withString:@"Hi"];
NSLog(@"%@", replacedStr); // Hi World
// 子串截取
NSString *subStr = [str1 substringToIndex:5];
NSLog(@"%@", subStr); // Hello
subStr = [str1 substringFromIndex:6];
NSLog(@"%@", subStr); // World
subStr = [str1 substringWithRange:NSMakeRange(2, 5)];
NSLog(@"%@", subStr); // llo W
// 字符串拆分
NSArray *components = [str1 componentsSeparatedByString:@" "];
NSLog(@"%@", components); // 两个字符串:Hello, World
// 字符串转换
int num = [@"88" intValue];
NSLog(@"%d", num); // 88
// 字符串比较
NSString *cmp1 = @"Hello";
NSString *cmp2 = @"Hello";
if ([cmp1 isEqualToString:cmp2]) {
NSLog(@"Strings are equal");
}
// -- NSMutableString 可变字符串
// 创建
NSMutableString *mutStr = [NSMutableString stringWithString:@"Hello"];
NSLog(@"%@", mutStr);
// 拼接
[mutStr appendString:@" World"];
NSLog(@"%@", mutStr);
// 插入
[mutStr insertString:@"Hi " atIndex:0];
NSLog(@"%@", mutStr);
// 删除
[mutStr deleteCharactersInRange:NSMakeRange(0, 3)];
NSLog(@"%@", mutStr);
[mutStr replaceOccurrencesOfString:@"World" withString:@"Universe" options:NSLiteralSearch range:NSMakeRange(0, [mutStr length])];
NSLog(@"%@", mutStr);
// 创建数组
NSArray *array = @[@"Taobao", @"Tmall", @"AMap"];
NSLog(@"%@", array);
// 获取数组元素数量
NSUInteger count = [array count];
NSLog(@"Count: %lu", (unsigned long)count);
// 获取指定索引处的元素
NSString *element = [array objectAtIndex:1];
NSLog(@"%@", element);
// 判断数组是否包含指定元素
BOOL containsElement = [array containsObject:@"Taobao"];
NSLog(@"Contains Taobao: %d", containsElement);
// 查找指定元素的索引
NSUInteger index = [array indexOfObject:@"Tmall"];
NSLog(@"Index of Tmall: %lu", (unsigned long)index);
// 数组元素的遍历
for (NSString *str in array) {
NSLog(@"%@", str);
}
// 系统提供方法
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%lu -%@", (unsigned long)idx, obj);
// 遍历到第二个停止
if (idx == 1) {
*stop = YES;
}
}];
// 支持正反遍历
[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%lu -%@", (unsigned long)idx, obj);
}];
// 可变数组的操作
NSMutableArray *mutArray = [NSMutableArray arrayWithArray:array];
NSLog(@"%@", mutArray);
// 添加元素
[mutArray addObject:@"Home"];
NSLog(@"%@", mutArray);
// 插入元素
[mutArray insertObject:@"InfoFlow" atIndex:2];
NSLog(@"%@", mutArray);
// 删除元素
[mutArray removeObject:@"Tmall"];
NSLog(@"%@", mutArray);
// 替换元素
[mutArray replaceObjectAtIndex:0 withObject:@"GuangGuang"];
NSLog(@"%@", mutArray);
// 数组元素的倒序排列
NSArray *reversedArray = [[mutArray reverseObjectEnumerator] allObjects];
NSLog(@"%@", reversedArray);
// 创建字典
NSDictionary *dict = @{@"name": @"John", @"age": @25, @"city": @"HangZhou"};
NSLog(@"%@", dict);
// 获取字典键值对数量
NSUInteger count = [dict count];
NSLog(@"Count: %lu", (unsigned long)count);
// 获取指定键的值
NSString *value = [dict objectForKey:@"name"];
NSLog(@"%@", value);
// 判断字典是否包含指定键
BOOL containsKey = [dict objectForKey:@"age"] != nil;
NSLog(@"Contains age: %d", containsKey);
// 获取所有键的集合
NSArray *keys = [dict allKeys];
NSLog(@"%@", keys);
// 获取所有值的集合
NSArray *values = [dict allValues];
NSLog(@"%@", values);
// 字典的遍历
for (NSString *key in dict) {
NSString *value = [dict objectForKey:key];
NSLog(@"%@: %@", key, value);
}
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"%@: %@", key, obj);
}];
// 可变字典的操作
NSMutableDictionary *mutDict = [NSMutableDictionary dictionaryWithDictionary:dict];
NSLog(@"%@", mutDict);
// 添加键值对
[mutDict setObject:@"Male" forKey:@"gender"];
NSLog(@"%@", mutDict);
// 删除键值对
[mutDict removeObjectForKey:@"age"];
NSLog(@"%@", mutDict);
// 替换键值对
[mutDict setObject:@"Los Angeles" forKey:@"city"];
NSLog(@"%@", mutDict);