OC读书笔记——对象复制

本文详细介绍了Objective-C中对象复制的两种方法:copy和mutableCopy。通过实例代码展示了它们的区别,包括对可变性和深浅复制的影响。还探讨了如何在自定义类中实现复制,以及浅复制和深复制的概念和实现。同时,讨论了在自定义类中重写copyWithZone:方法以实现深复制的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对象复制

OC提供了两种复制对象的方法,一种为copy,另一种为mutableCopy。

copy和mutable方法

两种方法都是用来复制对象的副本,区别在于
1.copy方法的返回对象总是不可以修改的副本,如果对其进行修改,那么就会报错,即使复制的是NSMutableString类型的字符串,也不可以修改副本。
2.mutableCopy方法的返回对象是一个可以修改的脚本,即使复制的是不可变字符串NSString,副本也可以进行修改,并且修改副本时,不会影响原来的字符串。
下面的这两种方法的一些代码实现:

//
//  main.m
//  NStry
//
//  Created by 差不多先生 on 2021/6/5.
//

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableString* book = [NSMutableString stringWithString:@"疯狂iOS讲义"];
        // 复制book字符串的可变副本
        NSMutableString* bookCopy = [book mutableCopy];
        // 修改副本对原字符串无任何影响
        [bookCopy replaceCharactersInRange:NSMakeRange(2, 3) withString:@"Android"];
        // 观察原字符串已经副本的变化
        NSLog(@"%@" , book);
        NSLog(@"%@" , bookCopy);
        NSString* str = @"fkit";
        // 复制不可变字符串的可变副本
        NSMutableString* strCopy = [str mutableCopy];
        // 1.向可变字符串后面追加字符串
        [strCopy appendString:@".org"];
        NSLog(@"%@" , strCopy);
        NSMutableString* bookCopy2 = [book copy];
        // [bookCopy2 appendString:@"aa"];
        return 0;
    }
}

在程序开始,对副本进行了修改,再分别打印原字符串和副本
得到的结果如下:
在这里插入图片描述
只是副本得到了修改。
最后注释的代码是报错的,因为他是使用了copy方法得到的字符串是不可以对其进行修改的。

NSString协议和NSMutableing协议

copy和mutableCopy方法复制对象十分方便,但他不可以复制自定义类。
这里定义了一个FKDog类。尝试复制自定义类。
接口部分:

#import <Foundation/Foundation.h>

@interface FKDog : NSObject
@property (nonatomic, strong) NSMutableString* name;
@property (nonatomic, assign) int age;

@end

主函数:

#import <Foundation/Foundation.h>
#import "FKDog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        FKDog* dog1 = [[FKDog alloc] init];
        dog1.name = [NSMutableString stringWithString:@"旺财"];
        dog1.age = 10;
        // FKDog* dog1Copy = [dog1 copy];
        return 0;
    }
}

上面这段代码中注视的语句会进行报错,Xcode显示错误为: Thread 1: "-[FKDog copyWithZone:]: unrecognized selector sent to instance 0x100709ae0"
提示找不到copyWithZone方法,其实NSObject中提供的copy方法返回的就是copyWithZone方法的返回值,但不支持复制自定义类,若要复制自定义类,则需要在接口部分实现NSString协议,并在实现部分加上copyWithCopy方法,代码如下
实现部分:

#import "FKDog.h"

@implementation FKDog
@synthesize  name = _name;
@synthesize age = _age;
- (id)copyWithZone:(NSZone*)zone {
    NSLog(@"--执行copyWithZone:--");
    FKDog* dog = [[[self class] allocWithZone:zone] init];
    dog.name = self.name;
    dog.age = self.age;
    return  dog;
}
@end

加入上述代码后,便可以实现使用copy方法对自定义类的复制。

FKDog* dog1Copy = [dog1 copy];
        dog1Copy.age = 12;
        dog1Copy.name = [NSMutableString stringWithString:@"snoopy"];

在上述的代码中,对复制的副本进行了修改,尽管我们使用了copy方法,按道理复制的对象应该不可以改变,但由于我们自定义的类没有不可变类,所以可以进行修改。
最后强调,如果重写父类时,其父类实现NSCopy协议并重写了copyWithZone:方法时,应该先使用父类的copy方法复制父类的成员变量再重写子类的方法,再对子类定义的成员变量赋值。
代码格式如下:

- (id)copyWithZone:(NSZone*)zone {
    id cpy = [super copy];
    // 对子类变量赋值
    ...........
    return cpy;
}

浅复制与深复制

在上面的代码中如下修改副本的值

 [dog1Copy.name replaceCharactersInRange:NSMakeRange(0, 2) withString:@"snoopy"];

再输出原字符串和副本,会发现他俩相同,这是因为在重写的方法中,只是让副本的name变量和原对象的name变量指向了同一个字符串,name存储的仅仅是地址,所以对其进行修改时,实际是对他实际指向的NSMutable字符串进行修改,输出的结果相同。
对于上述这种复制方式,称为浅复制:

程序仅仅复制了指针的地址,而并非指针指向的对象

深复制则与其完全不同,不仅会复制指向的对象,还会递归复制每个指针类型的属性,直到两个对象没有公用的部分。
采用深复制可以重写上面的copyWithZone:方法,代码如下:

- (id)copyWithZone:(NSZone*)zone {
    NSLog(@"--执行copyWithZone:--");
    FKDog* dog = [[[self class] allocWithZone:zone] init];
    // 将原对象的name实例变量赋值一份然后赋给新对象的name实例变量。
    dog.name = [self.name mutableCopy];
    dog.age = self.age;
    return  dog;
}

重写的方法并不是简单将原对象的属性赋给新对象,而是复制了一个新的可变副本赋值给新对象,这样就可以保证二者无公用部分,实现了深复制。
这样重新打印上面的两个对象,修改复制对象的值并不会影响原对象。
深复制的实现很复杂,尤其是当指针繁多的时候。
在这里插入图片描述

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值