首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 常用基礎類深度解析:NSString、NSMutableString、NSArray、NSMutableArray、NSNumber、NSValue

     編輯:關於C語言

Foundation 基礎類體系:不可變/可變雙重體系、橋接機制、工廠方法與現代語法

Foundation 框架提供的基礎類是 OC 開發的語言級運行時支持。本文系統梳理字符串、數組、數值包裝、結構體包裝六大核心類簇,對比不可變/可變語義、內存管理、性能特徵、現代字面量語法與經典工廠方法,並給出工程級最佳實踐。

一、 字符串類簇:NSString` / NSMutableString`

1. 不可變字符串 NSString`

// 現代字面量語法 (編譯期常量,存儲在數據段)
NSString *str = @"Hello 郭String";

// 經典工廠方法
NSString *str2 = [NSString stringWithFormat:@"hehe %@ %@", @"hhh", @"jjj"];

// 核心屬性
NSUInteger len = str.length; // UTF-16 代碼單元數,非字符數(Emoji 佔2)

// 子串提取
NSString *sub1 = [str substringFromIndex:5];      // 從索引 5 到末尾
NSString *sub2 = [str substringToIndex:5];        // 從開頭到索引 5(不含)
NSRange range = NSMakeRange(2, 3);
NSString *sub3 = [str substringWithRange:range];  // 指定範圍

// 拼接 (返回新字符串)
NSString *cat1 = [str stringByAppendingString:@"IOS"];
NSString *cat2 = [str stringByAppendingFormat:@" %@ %@", @"A", @"B"];

// 替換 (返回新字符串)
NSString *replaced = [str stringByReplacingOccurrencesOfString:@"String" withString:@"World"];

// 比較
BOOL equal = [str isEqualToString:@"Hello"];      // 內容比較
BOOL hasPrefix = [str hasPrefix:@"Hello"];        // 前綴
BOOL hasSuffix = [str hasSuffix:@"png"];          // 後綴

// 關鍵:NSString 不可變,所有「修改」操作實際創建新對象

2. 可變字符串 NSMutableString` (NSString 子類)

NSMutableString *mStr = [NSMutableString stringWithString:@"Hello"]; // 基於現有創建
// 或 [NSMutableString string] 創建空串

// 就地修改 (不創建新對象)
[mStr appendString:@"Guozai"];           // 追加字符串
[mStr appendFormat:@" %d", 123];         // 格式化追加
[mStr deleteCharactersInRange:NSMakeRange(4, 1)]; // 刪除範圍
[mStr replaceCharactersInRange:NSMakeRange(3, 2) withString:@"YY"]; // 替換
[mStr insertString:@"TT" atIndex:2];     // 插入

// 繼承 NSString 所有只讀方法
NSUInteger len = mStr.length;
BOOL hasPre = [mStr hasPrefix:@"He"];

3. 選型指南

場景推薦類型理由
常量、配置、傳遞給 API、多線程共享NSString線程安全、語義清晰、編譯器優化 (常量合併)
頻繁拼接、構建大字符串、逐字符構建NSMutableString避免大量臨時對象分配/釋放,性能優勢顯著
JSON 序列化、網絡請求體構建NSMutableString 或 NSOutputStream流式寫入更適合超大數據

二、 數組類簇:NSArray` / NSMutableArray`

1. 不可變數組 NSArray`

// 現代字面量
NSArray *arr = @[@"Guozai", @"Guo", @"Zaiguo"]; // 以 nil 結尾 (字面量自動處理)

// 經典工廠
NSArray *arr2 = [NSArray arrayWithObjects:@"A", @"B", @"C", nil];

// 訪問
id first = arr.firstObject;      // nil 安全
id last = arr.lastObject;
id obj = arr[1];                 // 下標語法 (現代)
id obj2 = [arr objectAtIndex:1]; // 經典方法

// 遍歷
for (id obj in arr) { ... }      // 快速枚舉 (推薦)
for (NSUInteger i=0; i

2. 可變數組 NSMutableArray` (NSArray 子類)

NSMutableArray *mArr = [NSMutableArray arrayWithArray:arr]; // 基於現有創建
// 或 [NSMutableArray array] / [NSMutableArray arrayWithCapacity:10]

// 增
[mArr addObject:@"Guoguo"];              // 尾部添加
[mArr insertObject:@"New" atIndex:0];    // 指定位置插入

// 刪
[mArr removeObjectAtIndex:2];            // 按索引刪除
[mArr removeLastObject];                 // 刪除最後
[mArr removeObject:@"Guo"];              // 按值刪除 (第一個匹配)
[mArr removeObjectsInArray:@[@"A",@"B"]]; // 批量刪除

// 改
[mArr exchangeObjectAtIndex:0 withObjectAtIndex:mArr.count-1]; // 交換首尾
mArr[0] = @"NewValue";                   // 下標賦值 (現代語法)

// 查
NSUInteger idx = [mArr indexOfObject:@"Guozai"]; // 線性查找 O(n)
BOOL contains = [mArr containsObject:@"Guo"];    // 同 indexOfObject != NSNotFound

3. 實戰:可變數組管理模型對象 (圖書系統)

// Book 模型
@interface Book : NSObject
@property (copy) NSString *name;
@property (assign) CGFloat price;
- (instancetype)initWithName:(NSString *)name price:(CGFloat)price;
@end

// 使用
Book *b1 = [[Book alloc] initWithName:@"Guozai1" price:10];
Book *b2 = [[Book alloc] initWithName:@"Guozai2" price:15];
Book *b3 = [[Book alloc] initWithName:@"Guozai3" price:13];

NSMutableArray *books = [NSMutableArray arrayWithObjects:b1, b2, b3, nil];

// 添加/刪除
[books addObject:[[Book alloc] initWithName:@"Guozai4" price:12]];
[books removeObjectAtIndex:2];

// 遍歷輸出
for (Book *b in books) {
    NSLog(@"%@, %.2f", b.name, b.price);
}

// 查找
for (Book *b in books) {
    if ([b.name isEqualToString:@"Guozai3"]) {
        NSLog(@"Price: %f", b.price);
    }
}

// 排序:按價格降序 (冒泡演示,實際用 sortUsingComparator:)
for (int i=0; i

三、 數值包裝:NSNumber` — 基礎類型與對象橋接

// 裝箱:基本類型 → 對象
NSNumber *numInt = @100;                    // 現代語法 (編譯器自動推導類型)
NSNumber *numDbl = @3.14;
NSNumber *numBool = @YES;
// 等價經典: [NSNumber numberWithInt:100], numberWithDouble:, numberWithBool:

// 拆箱:對象 → 基本類型
int val = [numInt intValue];
double d = [numDbl doubleValue];
BOOL b = [numBool boolValue];
// 通用: [numInt integerValue], longLongValue, floatValue 等

// 集合存儲基本類型
NSMutableArray *arr = [NSMutableArray array];
[arr addObject:@42];        // 自動裝箱
int x = [arr[0] intValue];  // 手動拆箱

// 比較
NSComparisonResult cmp = [numInt compare:@200]; // -1/0/1
BOOL eq = [numInt isEqualToNumber:@100];        // 值相等

四、 結構體包裝:NSValue` — 非對象類型入集合

// CGPoint / CGSize / CGRect / CGAffineTransform 等 Core Graphics 結構體
CGPoint pt = CGPointMake(10, 20);
NSValue *val = [NSValue valueWithPoint:pt]; // 裝箱
CGPoint pt2 = [val pointValue];             // 拆箱

// 字符串化 (調試用)
NSLog(@"%@", NSStringFromPoint(pt2)); // 輸出 "{10, 20}"

// 其他結構體
CGSize sz = CGSizeMake(100, 200);
NSValue *szVal = [NSValue valueWithSize:sz];
CGSize sz2 = [szVal sizeValue];
NSLog(@"%@", NSStringFromSize(sz2)); // "{100, 200}"

// 自定義結構體 (需手動編碼/解碼)
typedef struct { int x; int y; } MyPoint;
MyPoint mp = {5, 6};
NSData *data = [NSData dataWithBytes:&mp length:sizeof(mp)]; // 序列化為 Data
[arr addObject:data]; // 存入數組
// 取出時: MyPoint mp2; [data getBytes:&mp2 length:sizeof(mp2)];

五、 核心設計模式總結

模式體現優勢
類簇NSString 實際是 __NSCFString 等私有子類統一接口,運行時根據數據特徵選擇最優實現 (如單字符優化、大字符串優化)
不可變/可變雙重體系NSArray`/NSMutableArray` 等語義明確,線程安全 (不可變),性能優化 (可變就地修改)
字面量語法@[], @{}, @()編譯期類型推導,生成靜態常量或優化調用,代碼簡潔
裝箱/拆箱NSNumber`, NSValue`基本類型/結構體無縫進入對象體系 (集合、KVC、Archiving)

最佳實踐:默認使用不可變類型 (NSString, NSArray, NSDictionary) 並配合現代字面量語法;僅在性能分析證明瓶頸或邏輯確需就地修改時 使用可變對應類型。利用 @() 自動裝箱基本類型,NSValue 包裝結構體,讓所有數據統一為對象流入集合/KVC/歸檔管線。記住:NSMutableString 等可變類是其不可變父類的子類,可直接傳遞給接收父類的參數(但語義上需謹慎)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved