Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在Swift中覆盖或绕过访问器_Objective C_Swift_Swift2_Setter_Getter Setter - Fatal编程技术网

Objective c 在Swift中覆盖或绕过访问器

Objective c 在Swift中覆盖或绕过访问器,objective-c,swift,swift2,setter,getter-setter,Objective C,Swift,Swift2,Setter,Getter Setter,我试图在Swift中复制Objective-C的ivar/setter访问。 以下是在Objective-C中使用setter与ivar的简单示例: @interface Person : NSObject @property (nonatomic, strong) NSString *name; @end @implementation Person - (void)setName:(NSString *)name { // Let's assume that this is a

我试图在Swift中复制Objective-C的ivar/setter访问。 以下是在Objective-C中使用setter与ivar的简单示例:

@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@end


@implementation Person

- (void)setName:(NSString *)name {
    // Let's assume that this is an expensive operation.
    // I want to perform it only when necessary.
    _name = name.capitalizedString;
}

- (void)someMutatingMethod1
{
    Person *otherPerson = nil; // Get a person
    NSString *newName = otherPerson.name;

    // At this point, I know that newName is in the corect format because it comes from a Person object.
    // I don't need the expensive setter work, so I bypass it with direct ivar access.
    _name = newName;
}

- (void)someMutatingMethod2
{
    NSString *userInputName = @"john";

    // It's user input, I need the setter to perform it's work.
    self.name = userInputName;
}

@end
在Swift中复制此类最接近的方法是:

class Person {
    private var _name: String?
    var name: String? {
        get {
            return _name
        }
        set (newName) {
            _name = newName?.capitalizedString
        }
    }

    func someMutatingMethod1() {
        let otherPerson:Person? = nil;
        _name = otherPerson?.name;
    }

    func someMutatingMethod2() {
        let userInputName = "john";
        self.name = userInputName;
    }

}
但这很痛苦,因为访问器不是自动合成的,我必须手动编写它们。这让人困惑,因为我现在可以使用
\u name
name
self.\u name
self.name

现在,关于堆栈溢出的大多数答案都建议我这样写:

class Person2 {
    var name: String? {
        didSet {
            self.name = self.name?.capitalizedString
        }
    }
}
但我认为这让人困惑,也不清楚我的意图。我不是在设置name属性后执行级联变异,而是在设置值之前变异传递给setter的值。再一次,我希望能够私下绕过这个setter,这是这种方法不可能做到的

为什么我不能这样写:

class Person2 {
    var name: String? {
        didSet {
            self.name = self.name?.capitalizedString
        }
    }
}
class Person3{
变量名称:字符串{
集合(新名称){
name=newName?.capitalizedString
}
}
}

//这实际上使编译器在Xcode 7.2上崩溃。您使用
\u name
的第一个实现是完全正确的,并且恰好与ObjC的工作方式完全匹配。它没有什么问题,代价可能是两行“不必要的”代码。正如您所注意到的,解决这个问题只会使事情变得更加复杂。它看起来是相同的,但工作原理不同,因为在这种情况下,
name
\u name
都是属性(为
\u name
合成了默认访问器)。但是,也许在Swift中不存在ivar和属性之间的分离?我仍然认为,为了清晰起见,我将在任何地方都使用此实现,但我很惊讶,没有一种内置的方法可以做到这一点,而不编写与Objective-C类似的大量代码。您是对的,没有强大的ivar/属性类似于ObjC中的复制。在大多数情况下,这是一个好处。如果您经常这样做(将属性设置为非其实际值的内容),您应该询问您是否在做其他错误的事情。通常,在foo.x=y之后,foo.x应该返回y。如果不是,它就不是一个真正的“属性”,您可能应该编写一个显式的updateX()方法来明确这一点(并使setter私有),而不是重写setter。也就是说,ObjC在处理CoreData或锁定时一直都有这种重复。您通常必须维护“基本”访问器。(请参见primitiveValueForKey:)您使用
\u name
的第一个实现是完全正确的,并且恰好与ObjC的工作方式完全匹配。它没有什么问题,代价可能是两行“不必要的”代码。正如您所注意到的,解决这个问题只会使事情变得更加复杂。它看起来是相同的,但工作原理不同,因为在这种情况下,
name
\u name
都是属性(为
\u name
合成了默认访问器)。但是,也许在Swift中不存在ivar和属性之间的分离?我仍然认为,为了清晰起见,我将在任何地方都使用此实现,但我很惊讶,没有一种内置的方法可以做到这一点,而不编写与Objective-C类似的大量代码。您是对的,没有强大的ivar/属性类似于ObjC中的复制。在大多数情况下,这是一个好处。如果您经常这样做(将属性设置为非其实际值的内容),您应该询问您是否在做其他错误的事情。通常,在foo.x=y之后,foo.x应该返回y。如果不是,它就不是一个真正的“属性”,您可能应该编写一个显式的updateX()方法来明确这一点(并使setter私有),而不是重写setter。也就是说,ObjC在处理CoreData或锁定时一直都有这种重复。您通常必须维护“基本”访问器。(请参见primitiveValueForKey:)