详细讲解:Objective-C 基本类型、集合类和代码块
一、基本类型详解
1.1 主要基本类型
1// MyTypes.m 2#import <Foundation/Foundation.h> 3 4void demonstrateBasicTypes() { 5 NSLog(@"========== 基本类型演示 =========="); 6 7 // 1. BOOL 类型(实际上是 signed char) 8 BOOL isOpen = YES; // YES = 1, NO = 0 9 BOOL isClosed = NO; 10 NSLog(@"BOOL: isOpen = %d, isClosed = %d", isOpen, isClosed); 11 12 // 2. 整数类型 13 NSInteger integerNumber = 42; // 64位系统上为 long, 32位系统上为 int 14 NSUInteger unsignedInteger = 100; // 无符号整数 15 NSLog(@"NSInteger: %ld, NSUInteger: %lu", 16 (long)integerNumber, 17 (unsigned long)unsignedInteger); 18 19 // 3. 浮点数类型 20 CGFloat floatNumber = 3.14159; // 64位系统上为 double, 32位系统上为 float 21 double doubleNumber = 2.71828; 22 NSLog(@"CGFloat: %f, Double: %f", floatNumber, doubleNumber); 23 24 // 4. 字符和字符串 25 char character = 'A'; 26 const char *cString = "C String"; 27 NSString *nsString = @"Objective-C String"; 28 NSLog(@"char: %c, C String: %s, NSString: %@", character, cString, nsString); 29 30 // 5. 特殊对象类型 31 id genericObject = @"这是一个字符串对象"; // 可以指向任何Objective-C对象 32 SEL selector = @selector(description); // 方法选择器 33 Class stringClass = [NSString class]; // 类对象 34 35 NSLog(@"id对象: %@", genericObject); 36 NSLog(@"SEL: %@", NSStringFromSelector(selector)); 37 NSLog(@"Class: %@", stringClass); 38 39 // 6. instancetype (返回实例类型,用于初始化方法) 40 // 在自定义类中会自动推断类型 41 42 // 7. 数值包装类 NSNumber 43 NSNumber *intNumber = @42; // 字面量语法 44 NSNumber *floatNum = @3.14f; 45 NSNumber *boolNum = @YES; 46 NSNumber *charNum = @'X'; 47 48 NSLog(@"NSNumber int: %@", intNumber); 49 NSLog(@"NSNumber float: %@", floatNum); 50 NSLog(@"NSNumber bool: %@", boolNum); 51 NSLog(@"NSNumber char: %@", charNum); 52 53 // 从NSNumber提取值 54 int intValue = [intNumber intValue]; 55 float floatValue = [floatNum floatValue]; 56 BOOL boolValue = [boolNum boolValue]; 57 char charValue = [charNum charValue]; 58 59 NSLog(@"提取的值: int=%d, float=%f, bool=%d, char=%c", 60 intValue, floatValue, boolValue, charValue); 61} 62
1.2 类型转换和检查
1// TypeConversion.m 2#import <Foundation/Foundation.h> 3 4void demonstrateTypeConversion() { 5 NSLog(@"========== 类型转换演示 =========="); 6 7 // 基本类型之间的转换 8 NSInteger integer = 100; 9 CGFloat cgFloat = (CGFloat)integer; // 显式转换 10 NSLog(@"NSInteger %ld -> CGFloat %f", (long)integer, cgFloat); 11 12 // NSNumber 与基本类型的转换 13 NSNumber *number = @99; 14 NSInteger fromNumber = [number integerValue]; 15 NSLog(@"NSNumber %@ -> NSInteger %ld", number, (long)fromNumber); 16 17 // 类型检查 18 id object = @"Hello"; 19 20 // 检查是否是特定类 21 if ([object isKindOfClass:[NSString class]]) { 22 NSLog(@"对象是NSString或子类"); 23 } 24 25 // 检查是否是特定类(精确匹配) 26 if ([object isMemberOfClass:[NSString class]]) { 27 NSLog(@"对象是NSString(不是子类)"); 28 } 29 30 // 响应方法检查 31 if ([object respondsToSelector:@selector(length)]) { 32 NSLog(@"对象响应length方法"); 33 } 34 35 // 空值检查 36 id nilObject = nil; 37 if (nilObject == nil) { 38 NSLog(@"对象为nil"); 39 } 40 41 // 安全调用(如果对象为nil,调用不会崩溃) 42 [nilObject description]; // 什么也不发生 43 44 // 条件初始化 45 NSString *result = object ?: @"默认值"; 46 NSLog(@"结果: %@", result); 47} 48
二、集合类详解 2.1 NSArray / NSMutableArray
1// CollectionsDemo.m 2#import <Foundation/Foundation.h> 3 4void demonstrateArrays() { 5 NSLog(@"========== 数组演示 =========="); 6 7 // 1. 不可变数组 NSArray 8 // 字面量语法(推荐) 9 NSArray *immutableArray = @[@"苹果", @"香蕉", @"橙子", @"葡萄"]; 10 NSLog(@"不可变数组: %@", immutableArray); 11 12 // 传统创建方式 13 NSArray *traditionalArray = [NSArray arrayWithObjects:@"张三", @"李四", @"王五", nil]; 14 15 // 2. 访问数组元素 16 NSLog(@"第一个元素: %@", immutableArray[0]); // 下标访问 17 NSLog(@"第二个元素: %@", [immutableArray objectAtIndex:1]); // 方法访问 18 19 // 3. 遍历数组 20 NSLog(@"--- 快速枚举遍历 ---"); 21 for (NSString *fruit in immutableArray) { 22 NSLog(@"水果: %@", fruit); 23 } 24 25 NSLog(@"--- 传统for循环 ---"); 26 for (NSUInteger i = 0; i < [immutableArray count]; i++) { 27 NSLog(@"索引%lu: %@", (unsigned long)i, immutableArray[i]); 28 } 29 30 NSLog(@"--- 枚举器遍历 ---"); 31 NSEnumerator *enumerator = [immutableArray objectEnumerator]; 32 NSString *item; 33 while (item = [enumerator nextObject]) { 34 NSLog(@"枚举器: %@", item); 35 } 36 37 // 4. 数组操作 38 NSLog(@"数组长度: %lu", (unsigned long)[immutableArray count]); 39 NSLog(@"是否包含'香蕉': %@", [immutableArray containsObject:@"香蕉"] ? @"是" : @"否"); 40 NSLog(@"'橙子'的索引: %lu", (unsigned long)[immutableArray indexOfObject:@"橙子"]); 41 42 // 5. 子数组 43 NSArray *subArray = [immutableArray subarrayWithRange:NSMakeRange(1, 2)]; 44 NSLog(@"子数组: %@", subArray); 45 46 // 6. 数组合并 47 NSArray *array1 = @[@"A", @"B"]; 48 NSArray *array2 = @[@"C", @"D"]; 49 NSArray *mergedArray = [array1 arrayByAddingObjectsFromArray:array2]; 50 NSLog(@"合并后数组: %@", mergedArray); 51 52 // 7. 可变数组 NSMutableArray 53 NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:@[@"北京", @"上海"]]; 54 NSLog(@"原始可变数组: %@", mutableArray); 55 56 // 添加元素 57 [mutableArray addObject:@"广州"]; 58 [mutableArray addObject:@"深圳"]; 59 NSLog(@"添加后: %@", mutableArray); 60 61 // 插入元素 62 [mutableArray insertObject:@"杭州" atIndex:1]; 63 NSLog(@"插入后: %@", mutableArray); 64 65 // 替换元素 66 mutableArray[2] = @"南京"; 67 NSLog(@"替换后: %@", mutableArray); 68 69 // 删除元素 70 [mutableArray removeObject:@"上海"]; 71 [mutableArray removeObjectAtIndex:0]; 72 NSLog(@"删除后: %@", mutableArray); 73 74 // 8. 数组排序 75 NSArray *unsorted = @[@5, @2, @8, @1, @9]; 76 NSArray *sorted = [unsorted sortedArrayUsingSelector:@selector(compare:)]; 77 NSLog(@"排序前: %@", unsorted); 78 NSLog(@"排序后: %@", sorted); 79 80 // 9. 使用NSPredicate过滤 81 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self > 3"]; 82 NSArray *filtered = [unsorted filteredArrayUsingPredicate:predicate]; 83 NSLog(@"大于3的元素: %@", filtered); 84} 85
2.2 NSDictionary / NSMutableDictionary
1void demonstrateDictionaries() { 2 NSLog(@"========== 字典演示 =========="); 3 4 // 1. 不可变字典 NSDictionary 5 // 字面量语法(推荐) 6 NSDictionary *immutableDict = @{ 7 @"name": @"张三", 8 @"age": @25, 9 @"city": @"北京", 10 @"isStudent": @YES 11 }; 12 NSLog(@"不可变字典: %@", immutableDict); 13 14 // 传统创建方式 15 NSDictionary *traditionalDict = [NSDictionary dictionaryWithObjectsAndKeys: 16 @"李四", @"name", 17 @30, @"age", 18 nil]; 19 20 // 2. 访问字典值 21 NSLog(@"姓名: %@", immutableDict[@"name"]); // 下标访问 22 NSLog(@"年龄: %@", [immutableDict objectForKey:@"age"]); // 方法访问 23 24 // 3. 遍历字典 25 NSLog(@"--- 快速枚举遍历键 ---"); 26 for (NSString *key in immutableDict) { 27 id value = immutableDict[key]; 28 NSLog(@"%@: %@", key, value); 29 } 30 31 NSLog(@"--- 遍历键值对 ---"); 32 [immutableDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 33 NSLog(@"Block遍历: %@ = %@", key, obj); 34 // 可以设置 *stop = YES; 来停止遍历 35 }]; 36 37 // 4. 字典操作 38 NSLog(@"所有键: %@", [immutableDict allKeys]); 39 NSLog(@"所有值: %@", [immutableDict allValues]); 40 NSLog(@"键数量: %lu", (unsigned long)[immutableDict count]); 41 42 // 5. 可变字典 NSMutableDictionary 43 NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary]; 44 45 // 添加键值对 46 mutableDict[@"name"] = @"王五"; 47 [mutableDict setObject:@28 forKey:@"age"]; 48 [mutableDict setObject:@"上海" forKey:@"city"]; 49 NSLog(@"原始可变字典: %@", mutableDict); 50 51 // 修改值 52 mutableDict[@"age"] = @29; 53 NSLog(@"修改年龄后: %@", mutableDict); 54 55 // 删除键值对 56 [mutableDict removeObjectForKey:@"city"]; 57 NSLog(@"删除城市后: %@", mutableDict); 58 59 // 添加多个键值对 60 NSDictionary *newEntries = @{@"job": @"工程师", @"salary": @15000}; 61 [mutableDict addEntriesFromDictionary:newEntries]; 62 NSLog(@"添加多个后: %@", mutableDict); 63 64 // 6. 字典合并 65 NSDictionary *dict1 = @{@"a": @1, @"b": @2}; 66 NSDictionary *dict2 = @{@"b": @3, @"c": @4}; // 注意:b会覆盖 67 NSMutableDictionary *combined = [dict1 mutableCopy]; 68 [combined addEntriesFromDictionary:dict2]; 69 NSLog(@"合并后: %@ (b被覆盖为3)", combined); 70} 71
2.3 NSSet / NSMutableSet
1void demonstrateSets() { 2 NSLog(@"========== 集合演示 =========="); 3 4 // 1. 不可变集合 NSSet(无序,元素唯一) 5 NSSet *immutableSet = [NSSet setWithObjects:@"A", @"B", @"C", @"A", @"B", nil]; 6 NSLog(@"不可变集合 (自动去重): %@", immutableSet); 7 8 // 2. 遍历集合 9 NSLog(@"--- 快速枚举遍历 ---"); 10 for (NSString *element in immutableSet) { 11 NSLog(@"元素: %@", element); 12 } 13 14 NSLog(@"--- 枚举器遍历 ---"); 15 NSEnumerator *enumerator = [immutableSet objectEnumerator]; 16 id obj; 17 while (obj = [enumerator nextObject]) { 18 NSLog(@"枚举器: %@", obj); 19 } 20 21 // 3. 集合操作 22 NSSet *set1 = [NSSet setWithObjects:@"A", @"B", @"C", @"D", nil]; 23 NSSet *set2 = [NSSet setWithObjects:@"C", @"D", @"E", @"F", nil]; 24 25 // 交集 26 NSMutableSet *intersection = [set1 mutableCopy]; 27 [intersection intersectSet:set2]; 28 NSLog(@"交集 (set1 ∩ set2): %@", intersection); 29 30 // 并集 31 NSMutableSet *unionSet = [set1 mutableCopy]; 32 [unionSet unionSet:set2]; 33 NSLog(@"并集 (set1 ∪ set2): %@", unionSet); 34 35 // 差集 36 NSMutableSet *difference = [set1 mutableCopy]; 37 [difference minusSet:set2]; 38 NSLog(@"差集 (set1 - set2): %@", difference); 39 40 // 4. 可变集合 NSMutableSet 41 NSMutableSet *mutableSet = [NSMutableSet setWithObjects:@"苹果", @"香蕉", nil]; 42 NSLog(@"原始可变集合: %@", mutableSet); 43 44 // 添加元素 45 [mutableSet addObject:@"橙子"]; 46 [mutableSet addObject:@"苹果"]; // 重复元素不会被添加 47 NSLog(@"添加后: %@", mutableSet); 48 49 // 删除元素 50 [mutableSet removeObject:@"香蕉"]; 51 NSLog(@"删除后: %@", mutableSet); 52 53 // 5. NSCountedSet(可以统计元素出现次数) 54 NSCountedSet *countedSet = [NSCountedSet set]; 55 [countedSet addObject:@"苹果"]; 56 [countedSet addObject:@"香蕉"]; 57 [countedSet addObject:@"苹果"]; 58 [countedSet addObject:@"苹果"]; 59 60 NSLog(@"苹果出现次数: %lu", (unsigned long)[countedSet countForObject:@"苹果"]); 61 NSLog(@"香蕉出现次数: %lu", (unsigned long)[countedSet countForObject:@"香蕉"]); 62 NSLog(@"所有元素: %@", countedSet); 63 64 // 6. 集合与数组转换 65 NSArray *arrayWithDuplicates = @[@"A", @"B", @"A", @"C", @"B"]; 66 NSSet *uniqueSet = [NSSet setWithArray:arrayWithDuplicates]; 67 NSArray *uniqueArray = [uniqueSet allObjects]; 68 NSLog(@"原始数组: %@", arrayWithDuplicates); 69 NSLog(@"去重后集合: %@", uniqueSet); 70 NSLog(@"去重后数组: %@", uniqueArray); 71} 72
三、代码块(Blocks)详解 3.1 Blocks 基础
1// BlocksDemo.m 2#import <Foundation/Foundation.h> 3 4// 定义块类型 5typedef void (^SimpleBlock)(void); 6typedef int (^CalculatorBlock)(int, int); 7typedef NSString* (^FormatterBlock)(NSString*); 8 9void demonstrateBasicBlocks() { 10 NSLog(@"========== 代码块基础演示 =========="); 11 12 // 1. 无参数无返回值块 13 SimpleBlock simpleBlock = ^{ 14 NSLog(@"这是一个简单的代码块"); 15 }; 16 simpleBlock(); 17 18 // 2. 带参数和返回值的块 19 CalculatorBlock addBlock = ^(int a, int b) { 20 return a + b; 21 }; 22 23 CalculatorBlock multiplyBlock = ^int(int a, int b) { 24 return a * b; 25 }; 26 27 int sum = addBlock(10, 20); 28 int product = multiplyBlock(5, 6); 29 NSLog(@"加法结果: %d", sum); 30 NSLog(@"乘法结果: %d", product); 31 32 // 3. 使用typedef定义的块 33 FormatterBlock uppercaseBlock = ^(NSString *input) { 34 return [input uppercaseString]; 35 }; 36 37 FormatterBlock greetingBlock = ^(NSString *name) { 38 return [NSString stringWithFormat:@"你好, %@!", name]; 39 }; 40 41 NSLog(@"大写: %@", uppercaseBlock(@"hello")); 42 NSLog(@"问候: %@", greetingBlock(@"张三")); 43 44 // 4. 块作为方法参数 45 NSArray *numbers = @[@1, @2, @3, @4, @5]; 46 47 // 使用块遍历数组 48 [numbers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 49 NSLog(@"元素[%lu]: %@", (unsigned long)idx, obj); 50 51 // 可以提前停止遍历 52 if (idx == 2) { 53 *stop = YES; // 停止遍历 54 } 55 }]; 56 57 // 5. 块内访问外部变量 58 int externalValue = 100; 59 60 // 默认是只读访问 61 CalculatorBlock useExternalBlock = ^(int a, int b) { 62 // externalValue = 200; // 错误:不能修改外部变量 63 return a + b + externalValue; 64 }; 65 NSLog(@"使用外部变量: %d", useExternalBlock(1, 2)); 66 67 // 使用__block修饰符使变量在块内可修改 68 __block int mutableValue = 50; 69 SimpleBlock modifyExternalBlock = ^{ 70 mutableValue += 10; 71 NSLog(@"块内修改后: %d", mutableValue); 72 }; 73 74 NSLog(@"修改前: %d", mutableValue); 75 modifyExternalBlock(); 76 NSLog(@"修改后: %d", mutableValue); 77} 78
3.2 Blocks 内存管理
1void demonstrateBlockMemoryManagement() { 2 NSLog(@"========== 代码块内存管理演示 =========="); 3 4 // 1. 块捕获变量 5 NSString *capturedString = @"原始值"; 6 NSMutableArray *capturedArray = [NSMutableArray arrayWithObjects:@"A", @"B", nil]; 7 8 SimpleBlock captureBlock = ^{ 9 // 捕获对象引用(强引用) 10 NSLog(@"捕获的字符串: %@", capturedString); 11 NSLog(@"捕获的数组: %@", capturedArray); 12 13 // 可以修改捕获的可变对象 14 [capturedArray addObject:@"C"]; 15 }; 16 17 capturedString = @"修改后的值"; // 块捕获的是创建时的值 18 NSLog(@"修改字符串后: %@", capturedString); 19 captureBlock(); 20 NSLog(@"数组被块修改后: %@", capturedArray); 21 22 // 2. 避免循环引用 23 // 常见于对象持有块,块又捕获对象的情况 24 25 // 创建临时对象来演示 26 @autoreleasepool { 27 NSMutableArray *retainedArray = [NSMutableArray new]; 28 [retainedArray addObject:@"数据"]; 29 30 // 错误:会导致循环引用 31 // retainedArray 强引用 block 32 // block 强引用 retainedArray 33 // __weak typeof(retainedArray) weakArray = retainedArray; 34 35 // 正确:使用弱引用 36 __weak NSMutableArray *weakArray = retainedArray; 37 [retainedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 38 // 使用弱引用避免循环引用 39 if (weakArray) { 40 NSLog(@"安全访问: %@", [weakArray objectAtIndex:0]); 41 } 42 }]; 43 } 44 45 // 3. 块作为返回值 46 CalculatorBlock createMultiplier(float multiplier) { 47 // 返回的块捕获了multiplier参数 48 return ^(int number) { 49 return (int)(number * multiplier); 50 }; 51 } 52 53 CalculatorBlock timesTwo = createMultiplier(2.0); 54 CalculatorBlock timesThree = createMultiplier(3.0); 55 56 NSLog(@"2 * 5 = %d", timesTwo(5)); 57 NSLog(@"3 * 5 = %d", timesThree(5)); 58 59 // 4. 块的可变性和复制 60 SimpleBlock originalBlock = ^{ 61 NSLog(@"原始块"); 62 }; 63 64 // 将块复制到堆上(如果需要保存或在其他地方使用) 65 SimpleBlock copiedBlock = [originalBlock copy]; 66 copiedBlock(); 67} 68
3.3 Blocks 高级用法
1void demonstrateAdvancedBlocks() { 2 NSLog(@"========== 代码块高级用法演示 =========="); 3 4 // 1. 块作为字典值 5 NSDictionary *operationMap = @{ 6 @"add": ^(NSNumber *a, NSNumber *b) { 7 return @([a intValue] + [b intValue]); 8 }, 9 @"subtract": ^(NSNumber *a, NSNumber *b) { 10 return @([a intValue] - [b intValue]); 11 }, 12 @"multiply": ^(NSNumber *a, NSNumber *b) { 13 return @([a intValue] * [b intValue]); 14 } 15 }; 16 17 // 定义块类型以便从字典获取 18 typedef NSNumber* (^OperationBlock)(NSNumber*, NSNumber*); 19 20 OperationBlock addBlock = operationMap[@"add"]; 21 OperationBlock multiplyBlock = operationMap[@"multiply"]; 22 23 NSLog(@"10 + 5 = %@", addBlock(@10, @5)); 24 NSLog(@"10 * 5 = %@", multiplyBlock(@10, @5)); 25 26 // 2. 异步操作中使用块(回调) 27 void simulateAsyncOperation(NSString *input, void (^completion)(NSString *result, NSError *error)) { 28 // 模拟异步操作 29 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), 30 dispatch_get_main_queue(), ^{ 31 if (input.length > 0) { 32 NSString *result = [NSString stringWithFormat:@"处理后的: %@", [input uppercaseString]]; 33 completion(result, nil); 34 } else { 35 NSError *error = [NSError errorWithDomain:@"DemoError" 36 code:100 37 userInfo:@{NSLocalizedDescriptionKey: @"输入为空"}]; 38 completion(nil, error); 39 } 40 }); 41 } 42 43 NSLog(@"开始异步操作..."); 44 simulateAsyncOperation(@"hello world", ^(NSString *result, NSError *error) { 45 if (error) { 46 NSLog(@"异步操作错误: %@", error.localizedDescription); 47 } else { 48 NSLog(@"异步操作完成: %@", result); 49 } 50 }); 51 52 // 3. 链式调用模式 53 typedef NSString* (^StringProcessor)(NSString*); 54 55 StringProcessor (^createPipeline)(NSArray<StringProcessor>) = ^(NSArray<StringProcessor> processors) { 56 return ^(NSString *input) { 57 __block NSString *result = input; 58 [processors enumerateObjectsUsingBlock:^(StringProcessor processor, NSUInteger idx, BOOL *stop) { 59 result = processor(result); 60 }]; 61 return result; 62 }; 63 }; 64 65 // 创建处理链 66 NSArray *processors = @[ 67 ^(NSString *str) { return [str uppercaseString]; }, 68 ^(NSString *str) { return [str stringByReplacingOccurrencesOfString:@" " withString:@"_"]; }, 69 ^(NSString *str) { return [@"processed_" stringByAppendingString:str]; } 70 ]; 71 72 StringProcessor pipeline = createPipeline(processors); 73 NSString *finalResult = pipeline(@"hello world"); 74 NSLog(@"链式处理结果: %@", finalResult); 75 76 // 4. 块递归调用(需要__block修饰) 77 __block void (^recursiveBlock)(int); 78 79 recursiveBlock = ^(int n) { 80 if (n > 0) { 81 NSLog(@"递归深度: %d", n); 82 recursiveBlock(n - 1); // 递归调用 83 } 84 }; 85 86 NSLog(@"开始递归:"); 87 recursiveBlock(3); 88 89 // 5. 使用块实现排序 90 NSArray *people = @[ 91 @{@"name": @"张三", @"age": @25}, 92 @{@"name": @"李四", @"age": @30}, 93 @{@"name": @"王五", @"age": @22} 94 ]; 95 96 NSArray *sortedPeople = [people sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 97 NSNumber *age1 = obj1[@"age"]; 98 NSNumber *age2 = obj2[@"age"]; 99 return [age1 compare:age2]; 100 }]; 101 102 NSLog(@"按年龄排序:"); 103 [sortedPeople enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 104 NSLog(@" %@ - %@岁", obj[@"name"], obj[@"age"]); 105 }]; 106} 107
3.4 实际应用示例
1// 实际应用:用户数据管理器 2@interface UserDataManager : NSObject 3 4typedef void (^DataCompletion)(NSArray *users, NSError *error); 5typedef void (^UserAction)(NSDictionary *user); 6 7- (void)fetchUsersWithCompletion:(DataCompletion)completion; 8- (void)processUserWithID:(NSString *)userId action:(UserAction)action; 9 10@end 11 12@implementation UserDataManager 13 14- (void)fetchUsersWithCompletion:(DataCompletion)completion { 15 // 模拟网络请求 16 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 17 // 模拟数据处理 18 [NSThread sleepForTimeInterval:0.5]; 19 20 NSArray *users = @[ 21 @{@"id": @"1", @"name": @"张三", @"email": @"zhangsan@example.com"}, 22 @{@"id": @"2", @"name": @"李四", @"email": @"lisi@example.com"}, 23 @{@"id": @"3", @"name": @"王五", @"email": @"wangwu@example.com"} 24 ]; 25 26 // 回到主线程回调 27 dispatch_async(dispatch_get_main_queue(), ^{ 28 if (completion) { 29 completion(users, nil); 30 } 31 }); 32 }); 33} 34 35- (void)processUserWithID:(NSString *)userId action:(UserAction)action { 36 NSDictionary *user = @{@"id": userId, @"name": @"示例用户", @"status": @"active"}; 37 38 // 执行传入的块 39 if (action) { 40 action(user); 41 } 42} 43 44@end 45 46void demonstrateRealWorldExample() { 47 NSLog(@"========== 实际应用示例 =========="); 48 49 UserDataManager *manager = [UserDataManager new]; 50 51 // 1. 使用块处理异步数据获取 52 [manager fetchUsersWithCompletion:^(NSArray *users, NSError *error) { 53 if (error) { 54 NSLog(@"获取用户失败: %@", error.localizedDescription); 55 } else { 56 NSLog(@"获取到%lu个用户:", (unsigned long)users.count); 57 [users enumerateObjectsUsingBlock:^(NSDictionary *user, NSUInteger idx, BOOL *stop) { 58 NSLog(@" %@ - %@", user[@"name"], user[@"email"]); 59 }]; 60 } 61 }]; 62 63 // 2. 传递自定义处理逻辑 64 [manager processUserWithID:@"123" action:^(NSDictionary *user) { 65 NSLog(@"处理用户: %@", user[@"name"]); 66 // 这里可以执行任何自定义逻辑 67 }]; 68} 69 70// 主函数 71int main(int argc, const char * argv[]) { 72 @autoreleasepool { 73 demonstrateBasicTypes(); 74 demonstrateTypeConversion(); 75 demonstrateArrays(); 76 demonstrateDictionaries(); 77 demonstrateSets(); 78 demonstrateBasicBlocks(); 79 demonstrateBlockMemoryManagement(); 80 demonstrateAdvancedBlocks(); 81 demonstrateRealWorldExample(); 82 } 83 return 0; 84} 85
关键点总结
基本类型:
BOOL - Objective-C的布尔类型(YES/NO)
NSInteger/NSUInteger - 平台无关的整数类型
CGFloat - 图形相关的浮点类型
id/instancetype - 泛型对象类型
NSNumber - 基本类型的包装类
集合类:
NSArray/NSMutableArray - 有序集合,元素可重复
NSDictionary/NSMutableDictionary - 键值对集合
NSSet/NSMutableSet - 无序集合,元素唯一
NSCountedSet - 可计数的集合
代码块(Blocks):
语法:^返回值类型(参数列表) { 实现 }
特性:可捕获外部变量,可作为参数传递
内存:默认在栈上创建,使用copy可移动到堆
循环引用:使用__weak避免
应用:回调函数、异步操作、集合操作等
这些是Objective-C编程中最核心和常用的部分,熟练掌握它们对于iOS/macOS开发至关重要。