黑马程序员_OC中对象的复制

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

关于对象的浅复制与深复制

浅复制(shallow copy):不会复制所引用的对象,新复制的对象只会指向现有的引用对象。当复制一个NSArray类的对象时,复制的对象只会复制指向引用对象的指针,而不会复制引用对象本身。如果复制了一个包含5个NSString对象的NSArray对象,你最终得到的时5个可供程序使用的字符串对象,而不是10个。

深复制(deep copy):将复制所有的引用对象。如果NSArray的copy方法是深层复制,则在操作完成后得到10个字符串对象。

创建对象的副本

假设我们有一个Engine类。为了能够复制engine对象,Engine类需要采用NSCopying协议。下面是Engine类的新接口:

@interface Engine: NSObject <NSCopying>
@end

因为Engine类采用了NSCopying协议,所以我们必须实现copyWithZone:方法(关于NSCopying协议,上一篇博文已做了简单介绍)。zone是NSZ one类的一个对象,指向一块可供分配的内存区域。当你向一个对象发送copy消息时,该copy消息在到达你的代码前会被转换为copyWithZone:方法。

Engine类的copyWithZone:方法的实现如下:

@implementation Engine:

- (id) copyWithZone: (NSZone *)zone
{
	Engine *engineCopy;
	engineCopy = [[[self class] allocWithZone: zone] init];
	return engineCopy;
} // copyWithZone

由于Engine类没有实例变量,因此我们必须创建一个新的engine对象。copyWithZone:方法的首要任务是获得self参数所属得类,然后向self对象所属得类发送copyWithZone:消息,以分配内存并创建一个该类得新对象。最后,copyWithZone:方法给这个新对象发送allocWithZone:消息使其初始化。

由于allocWithZone:方法是一个类方法。我们需要发消息给一个类。在这里是Engine类。为什么不像下面这样写:

[Engine allocWithZone: zone];

因为,这行代码只适用于Engine类。如果我们创建了Engine类的子类。这就会变的的不适用了。所以我们应该通过[self class]获得当前这个类。

这个实例的完整代码如下:

Engine.h

#import <Cocoa/Cocoa.h>

@interface Engine : NSObject <NSCopying>
@end // Engine

Engine.m

#import "Engine.h"

@implementation Engine

- (id) copyWithZone: (NSZone *) zone
{
	Engine *engineCopy;
	engineCopy = [[[self class] allocWithZone: zone] init];
	
	return (engineCopy);
	
} // copyWithZone


- (NSString *) description
{
    return (@"I am an engine.  Vrooom!");
} // description

@end // Engine

main.m

#import <Foundation/Foundation.h>
#import "Engine.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Engine *engine = [[Engine alloc] init];
        NSLog(@"%@", engine);
        
        Engine *engineCopy = [engine copy];
        NSLog(@"%@", engineCopy);
        
    }
    return 0;
}

运行后,结果如下:


---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: tim_oc1init和tim_oc2init是STM32的定时器模块的函数,用于初始化定时器的输出比较通道1和通道2。其,tim_oc1init用于初始化通道1,tim_oc2init用于初始化通道2。这两个函数可以设置定时器的输出模式、极性、预分频器等参数,以满足不同的应用需求。 ### 回答2: tim_oc1init和tim_oc2init是两个函数,是在STM32开发使用的定时器输出比较功能函数。 首先,我们需要了解一下定时器和定时器输出比较的概念。定时器是一种可编程、周期性的计时器,它能够在一定时间内产生定时断或输出PWM信号。而定时器输出比较是指定时器对比较值进行比较,当定时器计数器计数值达到比较值时,定时器输出会发生变化。 tim_oc1init和tim_oc2init是用于设定定时器输出比较功能的函数,以tim_oc1init函数为例,它的具体功能包括: 1. 设定TIMx_CH1的输出模式和极性,可以选择PWM模式或脉冲模式,并可设定输出极性为正常或反转; 2. 设定比较值,即当计数器的值达到此值时触发输出; 3. 设定预分频系数和重载值,确定计时器的计数范围。 通过tim_oc1init和tim_oc2init函数的设定,可以实现定时器输出比较功能,可以控制各种电子设备的输出信号和开关控制,适用于各种行业的应用场景。在开发,根据具体需求使用不同的输出模式和比较值,可以实现多种不同的功能操作。 ### 回答3: tim_oc1init和tim_oc2init是针对定时器的两个初始化函数。 首先,定时器是嵌入式系统非常重要的一个模块,它可以通过计时和计数等方式实现各种定时和计时功能,比如控制LED灯闪烁、通过定时触发断来完成一些任务等。 而tim_oc1init和tim_oc2init则是针对定时器的输出比较功能而设置的两个初始化函数,用于配置定时器的输出比较通道1和通道2。 对于tim_oc1init而言,它可以设置如下几个参数:定时器的指针、比较输出模式、预分频系数、占空比等。其,比较输出模式有四种模式可供选择,分别为TIM_OCMode_Timing(定时模式)、TIM_OCMode_Active(有效电平模式)、TIM_OCMode_Inactive(无效电平模式)和TIM_OCMode_PWM1(脉冲宽度调制模式)。 而tim_oc2init则是针对定时器的输出比较通道2进行初始化,可以设置的参数与tim_oc1init相同,只不过它是控制通道2的输出状态。 需要注意的是,这两个函数都是基于STM32的定时器模块设计的,因此在使用它们时需要根据硬件平台来确定具体的实现方法和参数设置。 总的来说,tim_oc1init和tim_oc2init是非常重要的定时器初始化函数,可以方便地控制定时器的输出比较通道,从而实现各种自定义的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值