Objective-C 核心语法深度解析:基本类型、集合类与代码块实战指南

作者:奋斗理想日期:2026/1/16

详细讲解: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开发至关重要。


Objective-C 核心语法深度解析:基本类型、集合类与代码块实战指南》 是转载文章,点击查看原文


相关推荐


SPI通信:从原理到工程实践
我太浮躁2026/1/8

文章目录 1、概述2、什么是SPI?2.1 SPI的特点是什么? 3、SPI的历史发展3.1 SPI诞生3.2 为什么是SPI?3.3 SPI的一路升级3.3.1 标准 SPI (Standard SPI)3.3.2 Dual SPI & Quad SPI (QSPI)3.3.3 Octal SPI (OSPI) / xSPI3.3.4 eSPI (Enhanced SPI) 4、协议架构及通信原理4.1 SPI功能层级划分(非官方,但实用便于理解)4.1.1 物理层 :四线制结


[服务器][教程]EC2开启自定义端口
踏雪Vernon2025/12/30

网上很多教程并没有说这一点。直接就说新建安全组之后就可以用了。 很坑,我一直以为我的服务器服务搭建的有问题。因为即使端口开了,端口没有对应的服务用端口扫描也是显示无连接的!! 1. 新建安全组规则 进入“实例”页面中找到“安全组”。新建一个安全组 新建之后如下所示。 新建之后,并不是直接就可以用了。而是要进行绑定!这个一定要注意!!! 2. 修改安全组规则 点击实例之后,选择“操作”,更改安全组 之后在这里选择刚才创建的安全组即可。其他的VPC应该也是类似的。 被网上的教程坑了。大家注意甄


【前端必看】手把手教你把 Strapi 5 自动化部署到宝塔,再也不用手动传代码了!
知航驿站2025/12/21

前言 兄弟们,作为一名普通前端,每次写完接口还要自己登录服务器、手动上传代码、装依赖、再重启 PM2,这一套“广播体操”做下来,天都黑了。 今天咱们就花 10 分钟,把这套活儿交给 GitHub Actions。以后你只管在本地 git push,剩下的脏活累活全让机器人帮你干! 在线文档 在线源码 一、 整体思路(大白话版) 代码放 GitHub:这大家都会。 GitHub Actions 开工:你一推代码,它就跳出来执行一个脚本。 SSH 远程登录:GitHub 像个“代跑腿”的,拿着你的


Webpack打包机制与Babel转译原理深度解析
老前端的功夫2025/12/13

Webpack打包机制与Babel转译原理深度解析 引言:现代前端构建工具的核心原理 Webpack和Babel是现代前端开发不可或缺的两个核心工具。Webpack解决了模块化、资源管理和打包优化的难题,而Babel则确保了JavaScript代码的浏览器兼容性。理解它们的底层原理不仅有助于更好地配置和使用这些工具,还能在遇到复杂问题时快速定位和解决。 一、Webpack打包机制深度解析 1.1 Webpack核心概念与架构设计 Webpack的整体架构: // Webpack 的核心抽象概念


web3区块链-小镇店铺的 “借力办事”:call 与 delegatecall 的区别与联系Web3-智能合约-整数溢出攻击:“凭空造币”的秘密
想ai抽2025/12/4

加密小镇上有两家店: A 店(水果店):老板是 Alice,有自己的账本(合约存储),记录着 “苹果库存”(存储变量uint256 public appleStock = 100;),但没学会 “盘点库存”“修改库存” 的方法;B 店(管理咨询店):老板是 Bob,专门帮人做库存管理,有两套核心 “操作手册”(合约函数): checkStock():读取自己账本上的库存,返回数值;addStock(uint256 num):把自己账本上的库存增加num个。 A 店想复用 B 店的方法


怎么理解 HttpServletRequest @Autowired注入
それども2026/1/24

在你的代码中,@Autowired(required = false) private HttpServletRequest req 的 required = false 是多余的,甚至可能带来潜在问题。以下是详细分析: 1. 为什么 required = false 是多余的? (1) HttpServletRequest 的特殊性 由 Servlet 容器(如 Tomcat)管理:HttpServletRequest 是 Web 请求的上下文对象,在 Servlet 环境中必然存在(

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客