Skip to content

1. oc的一些比较碎的点

Hannah0103 edited this page Oct 15, 2025 · 8 revisions

深拷贝&浅拷贝

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

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

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

KVO

KVO 允许一个对象观察另一个对象的属性变化。当被观察的属性发生变化时,观察者会收到通知

  1. 创建被观察的对象
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) NSString *email;
@end

@implementation Person
@end
  1. 添加观察者
@interface ViewController : UIViewController
@property (nonatomic, strong) Person *person;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.person = [[Person alloc] init];
    
    // 添加观察者
    [self.person addObserver:self 
                  forKeyPath:@"name" 
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld 
                     context:NULL];
    
    [self.person addObserver:self 
                  forKeyPath:@"age" 
                     options:NSKeyValueObservingOptionNew 
                     context:NULL];
}

- (void)dealloc {
    // 重要:在 dealloc 中移除观察者
    [self.person removeObserver:self forKeyPath:@"name"];
    [self.person removeObserver:self forKeyPath:@"age"];
}

@end

  1. 实现观察方法
- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change 
                       context:(void *)context {
    
    if ([keyPath isEqualToString:@"name"]) {
        NSString *oldName = change[NSKeyValueChangeOldKey];
        NSString *newName = change[NSKeyValueChangeNewKey];
        NSLog(@"姓名从 %@ 改为 %@", oldName, newName);
        
    } else if ([keyPath isEqualToString:@"age"]) {
        NSNumber *newAge = change[NSKeyValueChangeNewKey];
        NSLog(@"年龄改为 %@", newAge);
        
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

4.触发观察

- (void)updatePersonInfo {
    // 这些操作会触发 KVO 通知
    self.person.name = @"张三";  // 触发 name 的观察
    self.person.age = 25;       // 触发 age 的观察
}

观察选项 (NSKeyValueObservingOptions)

// 提供新值
NSKeyValueObservingOptionNew

// 提供旧值
NSKeyValueObservingOptionOld

// 立即发送通知(添加观察者时)
NSKeyValueObservingOptionInitial

// 在变化前发送通知
NSKeyValueObservingOptionPrior

// 组合使用
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | 
                                   NSKeyValueObservingOptionOld | 
                                   NSKeyValueObservingOptionInitial;

字符串

// -- 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