首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现NSCopying和copyWithZone

实现NSCopying和copyWithZone
EN

Code Review用户
提问于 2014-10-26 16:19:28
回答 1查看 9.2K关注 0票数 2

我已经阅读了一些关于实现NSCopyingcopyWithZone的参考资料,但情况仍然不太清楚。我看到许多使用allocWithZone的实现,这似乎是不推荐的,而使用autorelease的实现,在ARC中似乎是不必要的。

我想知道我能不能用更简单的东西逃脱。就像这样:

MTSound.h

代码语言:javascript
复制
#import <Foundation/Foundation.h>

@interface MTSound : NSObject <NSCopying>

@property (nonatomic) float frequency;
@property (nonatomic) float amplitude;
@property (nonatomic) float duration;

// Designated Initializer
- (instancetype)initWithFrequency:(float)freq
                        amplitude:(float)amp
                         duration:(float)dur;

+ (instancetype)soundWithFrequency:(float)freq
                         amplitude:(float)amp
                          duration:(float)dur;

@end

MTSound.m

代码语言:javascript
复制
#import "MTSound.h"

@implementation MTSound

// Initializers

- (instancetype)initWithFrequency:(float)freq amplitude:(float)amp duration:(float)dur {
    if (self = [super init]) {
        _frequency = freq;
        _amplitude = amp;
        _duration = dur;
    }
    return self;
}

// Class factory methods

+ (instancetype) soundWithFrequency:(float)freq amplitude:(float)amp duration:(float)dur {
    return [[self alloc] initWithFrequency:freq amplitude:amp duration:dur];
}

// NSCopying protocol

- (id)copyWithZone:(NSZone *)zone {
    return [[self class] soundWithFrequency:self.frequency
                                  amplitude:self.amplitude
                                   duration:self.duration];
}

@end

这种方法有什么问题吗?如果是的话,正确的实现是什么?

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-10-27 12:23:28

你的实现在我看来不错。来自NSCopying引用:

实现此协议的选项如下:使用alloc和init实现NSCopying .在不继承copyWithZone的类中:。通过调用超类的NSCopying :在继承NSCopying行为时实现NSCopying。如果超类实现可能使用NSCopyObject函数,则对保留对象的指针实例变量进行显式赋值。实现NSCopying,方法是保留原始副本,而不是在类及其内容不可变时创建新副本。如果子类从其超类继承NSCopying并声明其他实例变量,则子类必须重写copyWithZone:以正确处理自己的实例变量,首先调用超类的实现。

因此,您只需要知道,如果要拥有继承自MTSound的类,那么它们需要先调用[super copyWithZone],然后初始化它们自己的实例变量。

您还可以考虑使用alloc和init的第一种选择。如果苹果不介意的话,那么如果你愿意的话,你也可以这么做。

在参考示例中,忽略传递给NSZonecopyWithZone参数似乎也很好。忽视这一论点似乎是一种普遍的做法。如果您感兴趣,这个堆栈溢出回答将更多地讨论NSZone

我只有几个关于代码的评论。在我看来,这些评论:

代码语言:javascript
复制
// Initializers
// Class factory methods
// NSCopying protocol

作为语用更有用,或者可以完全删除。如果你这样做的话:

代码语言:javascript
复制
#pragma mark - Initializer

然后,您将在Xcode中的方法浏览器中获得一个粗体标题,这对于在类中查找特定方法非常有用。这绝对是一个优先考虑的问题,但是像您这样的简单评论并没有那么有用,而且有点多余。

您的属性(如@property (nonatomic) float frequency; )不是readonly的原因吗?通过阅读代码,我无法判断它们以后是否会被修改,或者值是否始终保持不变。如果他们总是保持不变,我认为readonly是合适的。

总的来说,代码非常干净,易于理解。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/68012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档