Skip to content

1. oc的一些比较碎的点

Hannah0103 edited this page Dec 22, 2025 · 8 revisions

深拷贝&浅拷贝

浅拷贝:只拷贝对象本身,内容共享;深拷贝:创建新对象,内容独立

拷贝方式 非容器-不可变对象 非容器-可变对象 容器-不可变对象 容器-可变对象
copy 浅拷贝-不可变 深拷贝-不可变 浅拷贝-不可变 深拷贝-不可变
mutableCopy 深拷贝-可变 深拷贝-可变 深拷贝-可变 深拷贝-可变
  1. copy和mutableCopy是foundation框架下的两种拷贝方式;
  • copy:返回一个不可变对象
  • mutableCopy:返回一个可变对象
  1. 非容器对象 不可变:NSString、NSNumber 等 可变:NSMutableString、NSMutableData 等

  2. 容器对象 不可变:NSArray、NSDictionary、NSSet 等 可变:NSMutableArray、NSMutableDictionary、NSMutableSet 等

Block - “就像一个一次性便条,小任务就地解决”

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);

Clone this wiki locally