OC学习Foudation框架

OC学习:Foudation框架

文章目录

字符串

在OC中,NSString代表字符序列不可变的字符串,NSMutableString代表字符序列可变的字符串

创建字符串

下面是创建NSString的几种方法

  1. 字面量语法

    objectivec 复制代码
    NSString* s1 = @"Hello";
    NSString* s2 = @"张三";

    编译时创建,存储在常量区,全局共享,性能最佳

  2. 类方法

    1. stringWithFormat-格式化创建

      objectivec 复制代码
      NSString* s3 = [NSString stringWithFormat:@"%@, %@!", s1, s2];
    2. stringWithString-从另一个字符串创建

      ; 复制代码
      NSString* s4 = @"123";
      NSString* s5 = [NSString stringWithString : s4];
    3. stringWithUTF8String-从C字符串创建

      objectivec 复制代码
      char* s6 = "Hello";
      NSString* s7 = [NSString stringWithUTF8String : s6];
    4. stringWithContentsOfURL:encoding:error

      objectivec 复制代码
      NSString *str = [NSString stringWithContentsOfFile:@"/path/file.txt"
                                                encoding:NSUTF8StringEncoding
                                                   error:nil];

      在上面的类方法中,本身就包括了实例方法中的初始化方法

  3. 空字符串

    复制代码
    NSString* str = [[NSString alloc] init];

下面是创建NSMutableString的几种方法

  1. 创建空的可变字符串

    objectivec 复制代码
    NSMutableString *mStr = [NSMutableString string];
    NSMutableString *mStr = [[NSMutableString alloc] init];
  2. 从已有字符串创建

    objectivec 复制代码
    NSMutableString *mStr = [NSMutableString stringWithString:@"Hello"];
    NSMutableString *mStr = [[NSMutableString alloc] initWithString:@"Hello"];
  3. 指定初始容量

    objectivec 复制代码
    NSMutableString *mStr = [NSMutableString stringWithCapacity:10];
三种实现方法

NSString的三种实现方法为_NSCFConstantString_NSTaggedPointerString_NSCFString

  1. 常量字符串(__NSCFConstantString

创建方式:字面量 @"..."[[NSString alloc] init](空字符串)等。

特征:存储在程序的常量区(__TEXT 段),全局共享,生命周期与程序相同,无需内存管理,访问速度最快。

示例:NSString *str = @"hello";

  1. Tagged Pointer 字符串(NSTaggedPointerString

创建方式:通过 stringWithFormat: 等动态方式生成的短字符串(通常长度 ≤ 某个阈值(七个字节以内))。

特征:将字符串内容直接编码在指针值中,不分配堆内存或者栈内存,无引用计数开销,性能极高。

示例:NSString *str = [NSString stringWithFormat:@"he"];(如果内容足够短)

  1. 普通动态字符串(__NSCFString

创建方式:较长的字符串、可变字符串(NSMutableString)、或通过 stringWithFormat: 等生成的长字符串。

特征:在堆上分配内存,支持任意长度,使用引用计数管理,可变为可变字符串(NSMutableString 也是其子类)。

示例:NSString *str = [NSString stringWithFormat:@"hello world, this is a long sentence"];

字符串的常用方法
objectivec 复制代码
//
//  zifuchuan.m
//  Study
//
//  Created by 王子鸣 on 2026/3/26.
//

#import "zifuchuan.h"

@implementation zifuchuan

@end
int main(int argc, char* argv[]) {
  //不可变字符串
    NSString* s1 = @"Hello";
    NSString* s2 = @"张三";
    NSString* s3 = [NSString stringWithFormat:@"%@, %@!", s1, s2];
    NSLog(@"%@", s3);
    NSLog(@"字符串长度为%lu", (unsigned long) s3.length);//计算字符串长度
    NSString* s4 = [s3 uppercaseString];//全转变为大写字母
    NSString* s5 = [s3 lowercaseString];//全转变为小写字母
    NSLog(@"%@", s4);
    NSLog(@"%@", s5);
    NSString* s6 = [s3 stringByAppendingString:@"你好"];//往字符串里增加内容
    NSLog(@"%@", s6);
    NSString* s7 = [s3 substringToIndex:5];//截取前五个字符
    NSLog(@"%@", s7);
    NSString* s8 = [s3 substringFromIndex:5];//从第五个字符开始截取
    NSLog(@"%@", s8);
    NSString* s9 = [s2 substringWithRange:NSMakeRange(0, 1)];//从索引0开始截取1个字符
    NSLog(@"%@", s9);
  //可变字符串
    NSMutableString* s10 = [NSMutableString stringWithString:@"起源"];
    NSLog(@"%@", s10);
    [s10 appendString:@"追加"];//追加内容
    NSLog(@"%@", s10);
    [s10 insertString:@"插入" atIndex:3];//在索引3插入内容
    NSLog(@"%@", s10);
    [s10 replaceCharactersInRange:NSMakeRange(2, 3) withString:@"替换"];//将索引2之后的3个字符替换
    NSLog(@"%@", s10);
    [s10 deleteCharactersInRange:NSMakeRange(2, 3)];//将索引2之后的3个字符删除
    NSLog(@"%@", s10);
    return 0;
}

对象复制

copy和mutablecopy

NSObject提供了copy和mutablecopy方法,copy方法用于复制对象的副本,通常总是返回对象不可修改的副本,即使对象本身可以修改,mutablecopy用于复制对象的可变副本,通常总是返回对象可修改的副本,即使对象本身是不可修改的

上述两个方法返回的都是复制对象的副本,所以对复制的副本进行修改时,原对象通常不受影响。

objectivec 复制代码
NSMutableString* book = [NSMutableString stringWithString:@"疯狂iOS讲义"];
        //复制book(可变)字符串的可变副本
        NSMutableString* bookCopy = [book mutableCopy];
        [bookCopy replaceCharactersInRange:NSMakeRange(2, 3) withString:@"android"];
        //修改副本,对原字符串没有影响
        NSLog(@"book的值为:%@", book);
        //副本字符串发生了改变
        NSLog(@"bookCopy的值为:%@", bookCopy);

输出结果是疯狂iOS讲义和疯狂android讲义,可见,修改副本并不会改变原对象

objectivec 复制代码
				NSString* str = @"fkos";
        //复制不可变字符串str的可变副本
        NSMutableString* strCopy = [str mutableCopy];
        //向可变字符串后追加字符串
        [strCopy appendString:@".org"];
        NSLog(@"%@", strCopy);
        //调用book的copy方法,返回一个不可修改的副本
        NSMutableString* bookCopy2 = [book copy];
        //若此时对bookCopy进行修改,编译时不会报错,但是运行后代码就会出错,即下面注释的代码
        //[bookCopy2 appendString:@"very good"];

即使str不可变,但是mutablecopy后的strCopy可以修改,即使book是可变的,但是copy后的bookCopy2就是不能修改

NSCopying和NSMutableCopying协议

copy和mutabCopy确实很方便,但是对于我们自己定义的类,我们用不了这两个方法(运行中会显示找不到(mutable)copyWithZone方法),因为需要调用这两个方法,所以我们要让这个类实现NS(mutable)Copying协议和实现(mutable)copyWithZone方法

objectivec 复制代码
@interface FKDog : NSObject <NSCopying>
@property (nonatomic, strong) NSMutableString* name;
@property (nonatomic, assign) int age;
-(id) copyWithZone:(NSZone*)zone;
@end
objectivec 复制代码
@implementation FKDog
- (id) copyWithZone : (NSZone*)Zone
{
    FKDog* dog = [[[self class] allocWithZone: Zone]init];
    dog.name = self.name;
    dog.age = self.name;
    return dog;
}
@end
objectivec 复制代码
FKDog* dog1 = [FKDog new];
dog1.name = [NSMutableString stringWithString:@"旺财"];
dog1.age = 20;
FKDog* dog2 = [dog1 copy];
dog2.name = [NSMutableString stringWithString:@"来福"];
dog2.age = 12;
NSLog(@"dog1的名字是%@", dog1.name);
NSLog(@"dog1的年龄是%d", dog1.age);
NSLog(@"dog2的名字是%@", dog2.name);
NSLog(@"dog1的年龄是%d", dog2.age);

这样我们就可以实现自定义类的复制了

深浅拷贝

浅拷贝仅仅是复制原对象的地址,即原对象和副本使用一个内存地址,修改任何一个都会影响另外一个

深拷贝是将原对象的内容复制放在一个新的内存地址,两者互不影响

  1. 非容器类比如NSString,NSNumber等包装类

​ 对不可变对象(如 NSString)调用 copy,由于内容不可变,系统直接返回自身,而不是创建新对象。

​ 对可变对象(如 NSMutableString)调用 copy,返回一个不可变的副本(NSString),并复制内容。

​ 对任何对象调用 mutableCopy,都会返回一个新的可变副本(如 NSMutableString),即使原对象是不可变的,也会创建新对象 并复制内容。

  1. 容器类比如NSArray,NSSet,NSDictionary

    对不可变容器(如 NSArray)调用 copy,通常返回自身(优化)。

    对不可变容器调用 mutableCopy,返回一个新的可变容器(如 NSMutableArray),但元素仍是原数组中的对象(浅拷贝)。

    对可变容器(如 NSMutableArray)调用 copy,返回一个新的不可变容器,元素仍是原容器中的对象。

    对可变容器调用 mutableCopy,返回一个新的可变容器,元素仍是原容器中的对象。

三大容器

数组(Array)

数组用于存储有序的对象集合,允许重复元素。

不可变数组:NSArray

创建后内容不可变。

常用创建方式:字面量 @[obj1, obj2]arrayWithObjects:arrayWithArray: 等。

objectivec 复制代码
NSArray* arr = @[@4, @3, @2, @1];

访问:下标 array[index]objectAtIndex:

常用方法:countcontainsObject:indexOfObject:subarrayWithRange:sortedArrayUsingSelector: 等。

三种排序方法

  1. sortedArrayUsingFunction
objectivec 复制代码
@implementation shuzu
NSInteger inSort(id num1, id num2, void* context) {
    int val1 = [num1 intValue];
    int val2 = [num2 intValue];
    if (val1 > val2) {
        return NSOrderedAscending;
    }else if (val1 < val2) {
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}
@end
复制代码
arr = [arr sortedArrayUsingFunction:inSort context:nil];
  1. sortedArrayUsingSelector

    objectivec 复制代码
    arr = [arr sortedArrayUsingSelector:@selector(compare:)];
  2. sortedArrayUsingComparator

    objectivec 复制代码
    arr = [arr sortedArrayUsingComparator:^(id obj1, id obj2){
            int val1 = [obj1 intValue];
            int val2 = [obj2 intValue];
            if (val1 > val2) {
                return NSOrderedAscending;
            }else if (val1 < val2) {
                return NSOrderedDescending;
            } else {
                return NSOrderedSame;
            }
        }];
可变数组:NSMutableArray

继承自 NSArray,支持动态增删改。

objectivec 复制代码
NSMutableArray* arr1 = [@[@1, @2, @3, @4] mutableCopy];
NSMutableArray* arr1 = [NSMutableArray arrayWithObjects:@1, @2, @3, @4, nil];

添加:addObject:insertObject:atIndex:

objectivec 复制代码
[arr1 addObject:@5];

删除:removeObject:removeObjectAtIndex:removeLastObject

替换:replaceObjectAtIndex:withObject: 或下标赋值。

objectivec 复制代码
[arr1 replaceObjectAtIndex:2 withObject:@7];
遍历方式

快速枚举 for (id obj in array)

objectivec 复制代码
for (id object in arr) {
        NSLog(@"%@", object);
    }

Block 枚举 enumerateObjectsUsingBlock:

索引循环 for (NSInteger i = 0; i < array.count; i++)

适用场景

需要保持元素顺序、允许重复,或需要通过索引快速访问。

集合(Set)

集合存储无序、唯一的对象,常用于去重和快速成员检测。

  1. 不可变集合:NSSet

创建:[NSSet setWithObjects:obj1, obj2, nil][NSSet setWithArray:]

objectivec 复制代码
NSSet* set1 = [NSSet setWithObjects : @1, @2, @3, @3, nil];
NSArray* arr1 = @[@1, @2, @3, @3];
NSSet* set2 = [NSSet setWithArray: arr1];

检测:containsObject:(O(1) 平均)。

获取所有对象:allObjects

  1. 可变集合:NSMutableSet
objectivec 复制代码
NSMutableSet* set3 = [NSMutableSet setWithArray:arr1];

添加:addObject:(已存在则不添加)。

objectivec 复制代码
[set3 addObject:@2];
[set3 addObject:@4];

删除:removeObject:

objectivec 复制代码
[set3 removeObject:@2];

集合运算:unionSet:(并集)、intersectSet:(交集)、minusSet:(差集)。

objectivec 复制代码
NSMutableSet* set4 = [NSMutableSet setWithObjects : @1, @3, @3, @4, @5,nil];
NSMutableSet* set5 = [NSMutableSet setWithObjects : @1, @2, @3, nil];
NSMutableSet* set6 = [set5 mutableCopy];
[set6 unionSet : set4];
NSLog(@"%@", set6);
NSMutableSet* set7 = [set5 mutableCopy];
[set7 intersectSet:set4];
NSLog(@"%@", set7);
遍历方式

快速枚举:for (id obj in set)

objectivec 复制代码
for (id object in set3) {
        NSLog(@"%@", object);
    }

Block 枚举:enumerateObjectsUsingBlock:

objectivec 复制代码
[set3 enumerateObjectsUsingBlock:^(id obj, BOOL* stop) {
        if ([obj isEqual : @3]) {
            NSLog(@"已找到");
            *stop = YES;
        } else {
            NSLog(@"%@", obj);
        }
    }];
适用场景

需要保证元素唯一、快速判断是否存在、或进行集合运算(如并集、交集)。

字典(Dictionary)

字典存储键值对 (key-value),键唯一,值可以是任意对象。键通常使用 NSString,但也可以是任何遵守 NSCopying 协议的对象。

  1. 不可变字典:NSDictionary

字面量创建:@{key1: value1, key2: value2}

objectivec 复制代码
NSDictionary *person = @{
            @"name": @"张三",
            @"age": @25,
            @"city": @"北京"
        };

取值:dict[key]objectForKey:

objectivec 复制代码
NSString *name = person[@"name"];
NSNumber *age = person[@"age"];
NSString *city = [person objectForKey:@"city"];

常用方法:allKeysallValuescountisEqualToDictionary:

  1. 可变字典:NSMutableDictionary

添加/修改:setObject:forKey:dict[key] = value

objectivec 复制代码
[mutablePerson setObject:@"男" forKey:@"gender"];
mutablePerson[@"age"] = @26; 

删除:removeObjectForKey:removeAllObjects

objectivec 复制代码
[mutablePerson removeObjectForKey:@"city"];
遍历方式

快速枚举遍历键:for (id key in dict)

objectivec 复制代码
for (NSString *key in mutablePerson) {
            NSLog(@"快速枚举: %@ = %@", key, mutablePerson[key]);
        }

Block 枚举:enumerateKeysAndObjectsUsingBlock:

objectivec 复制代码
[mutablePerson enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
            NSLog(@"Block 枚举: %@ = %@", key, value);
            if ([key isEqualToString:@"job"]) {
                *stop = YES;  // 找到 job 后停止
            }
        }];
适用场景

需要通过唯一标识符(键)快速查找数据,如用户配置、网络请求参数等。

相关推荐
yyk的萌3 小时前
AI 应用开发工程师基础学习计划
开发语言·python·学习·ai·lua
亘元有量-流量变现4 小时前
APP自动识别跳转各大应用商店(鸿蒙+iOS+安卓全品牌)|可直接部署落地页源码
android·ios·harmonyos
龘龍龙4 小时前
大模型学习(三)-RAG、LangChain
学习·langchain
计算机安禾5 小时前
【数据结构与算法】第22篇:线索二叉树(Threaded Binary Tree)
c语言·开发语言·数据结构·学习·算法·链表·visual studio code
计算机安禾5 小时前
【数据结构与算法】第21篇:二叉树遍历的经典问题:由遍历序列重构二叉树
c语言·数据结构·学习·算法·重构·visual studio code·visual studio
信奥胡老师5 小时前
P1255 数楼梯
开发语言·数据结构·c++·学习·算法
夜幕下的ACM之路6 小时前
一、基础知识学习(Transformer + 上下文窗口 + Token 计算 + Embedding 向量)
人工智能·学习·transformer·embedding
GHL2842710906 小时前
Base64学习
学习