Ios 斯威夫特如何;“传递值”;物体的形状

Ios 斯威夫特如何;“传递值”;物体的形状,ios,swift,Ios,Swift,我对斯威夫特很陌生。我创建了一个类(例如): 我还构建了一个in-other类函数: class func A_plusplus(f:Fraction){ f.a++ } 然后在行政课上我写: var object = Fraction(a:10) print("before run func = " + object.toString()) XXXclass.A_plusplus(object) print("after ran func =" + object.toString()

我对斯威夫特很陌生。我创建了一个类(例如):

我还构建了一个in-other类函数:

class func A_plusplus(f:Fraction){
    f.a++
}
然后在行政课上我写:

var object = Fraction(a:10)
print("before run func = " + object.toString())
XXXclass.A_plusplus(object)
print("after ran func =" + object.toString() )
因此,控制台输出是

运行前func=10;运行后func=11

问题是我如何发送一个“object”的副本以保持其值等于10

如果函数总是通过引用传递,为什么我们仍然需要关键字:
“inout”

A\u plusplus(&object)/[如果我将参数设置为inout参数]
A\u plusplus(object)

一般来说,我不想使用
struct
。虽然这会解决我的问题 问题是,我很少通过值传递。所以我不想要程序的 复制过程会降低我的用户手机的速度:(

而且似乎符合
NSCopying
协议是一个不错的选择 我不知道如何实现该功能:
func copyWithZone(区域:
NSZone)->AnyObject?
正确


Swift有一个新概念,称为“结构”

可以将分数定义为结构(而不是类)

如果您使用struct,那么尝试在函数中使用inout
希望这对您有所帮助。

如果您的类是NSObject的子类,最好使用
NSCopying

class Fraction:NSObject,NSCopying{
var a:Int
var b:NSString?
required init(a:Int){
    self.a = a
}
func toString() -> String{
    return "\(self.a)"
}
func copyWithZone(zone: NSZone) -> AnyObject {
    let theCopy=self.dynamicType.init(a: self.a)
    theCopy.b = self.b?.copy() as? NSString
    return theCopy
}
}
class XXXclass{
class func A_plusplus(f:Fraction){
    f.a++
    f.b = "after"
}
}

如果它只是一个普通的swift类,那么必须创建一个copy方法

class Fraction{
var a: Int
init(a:Int){
    self.a = a
}
func toString() -> String{
    return "\(self.a)"
}
func copy()->Fraction{
    return Fraction(a: self.a)
}
}
class XXXclass{
    class func A_plusplus(f:Fraction){
        f.a++
   }
}
var object = Fraction(a:10)
print("before run func = " + object.toString())
XXXclass.A_plusplus(object.copy())
print("after ran func =" + object.toString() )
为了清楚起见,您必须知道swift中主要有两种类型

  • 引用类型。如类实例、函数类型
  • 值类型,如结构和其他类型(不是类实例或函数类型)
  • 如果传入引用类型,传入引用的副本,它仍然指向原始对象

    如果传入副本类型,则传入值的副本,因此它与原始值无关

    让我们来谈谈
    inout
    ,如果您使用它,它会传入相同的对象或值。它对值类型有影响

    func add(inout input:Int){
        input++
    }
    
    var a = 10
    print(a)//10
    add(&a)
    print(a)//11
    
    我怎样才能发送一个“对象”的副本来保持其值等于10

    在Swift中,类和函数始终通过引用传递。结构、枚举和基元类型通过值传递。请参阅

    不能按值传递对象。在按引用传递对象之前,必须手动复制它(如果这是您真正想要的)

    另一种方法是将您的
    转换为
    结构
    ,因为它随后将按值传递。但是,请记住还有一些其他方法,它可能不一定是您想要的

    如果函数总是通过引用传递,为什么我们仍然需要关键字:“inout”

    根据,在以下情况下使用,
    inout

    如果希望函数修改参数的值,并且希望这些更改在函数调用结束后保持不变,请将该参数定义为in-out参数

    因此,在实践中,使用
    inout
    可以通过引用传递值类型(如struct或primitive)。您不应该经常使用它。Swift提供了,可以使用它

    A\u plusplus(&object)/[如果我将参数设置为inout参数]
    A\u plusplus(object)

    A_plusplus
    函数没有区别。在该函数中,您不修改参数
    f
    本身,而是修改
    f.A
    属性

    下面的示例显示了在传递类对象时使用
    inout
    的效果。这两个函数相同,只是参数定义不同

    class Person {
        var name: String
        init(name: String) { self.name = name }
    }
    
    var me = Person(name: "Lennon") // Must be var to be passed as inout
    
    // Normal object by reference with a var
    func normalCall(var p: Person) {
        // We sure are able to update p's properties,
        // and they will be reflected back to me
        p.name = "McCartney"
        // Now p points to a new object different from me,
        // changes won't be reflected back to me
        p = Person(name: "Ringo")
    }
    
    // Inout object reference by value
    func inoutCall(inout p: Person) {
        // We still can update p's properties,
        p.name = "McCartney"
        // p is an alias to me, updates made will persist to me
        p = Person(name: "Ringo")
    }
    
    print("\(me.name)") //--> Lennon
    
    normalCall(me)
    print("\(me.name)") //--> McCartney
    
    inoutCall(&me)
    print("\(me.name)") //--> Ringo
    
    normalCall
    p
    me
    中,是指向同一对象的不同变量。当您实例化一个新对象并将其分配给
    p
    时,它们不再引用同一对象。因此,对该新对象的进一步更改不会反映回
    me

    声明
    p
    var
    参数只意味着其值可以在整个函数中更改,并不意味着新值将分配给作为参数传递的对象


    另一方面,在
    inoutCall
    中,您可以将
    p
    me
    视为别名。因此,将新对象分配给
    p
    与将新对象分配给
    me
    完全相同。
    p
    的任何更改都会在函数结束后保留在
    me
    中。

    谢谢!我注意到了但是我的类有很大的内容,我可以把(类)改成(结构)吗?@Microos。如果你使用类,那么你应该让你的类符合NSCopying协议,并且你应该使用mutableCopy()功能,而不是直接指派。谢谢!这是一个很好的解决方案!我想我对我一直认为的很好:DThis很好,但是我更喜欢使用nScVIGIN(复制功能有点荒谬)。如果使用
    NSCopying
    ,则必须使其成为NSObject的子类。它不适合Swift类。我可以忽略NSCopying吗。要生成副本()指定具有完全相同属性的新对象的函数?如果您的类是NSObject的子类,您最好使用
    NScopying
    ,否则您可以只制作一个复制函数来返回一个新实例谢谢!我想我了解得更深入了!但我不会使用struct,因为在我的项目的大多数情况下,我都使用past被引用。所以总是复制值会使它在函数1中效率更低,为什么分配一个新人(Ringo)工作更少。我认为函数正在给“我”分配一个不同的引用。我在答案中添加了关于示例代码的进一步解释,包括
    var
    inout
    class Fraction{
    var a: Int
    init(a:Int){
        self.a = a
    }
    func toString() -> String{
        return "\(self.a)"
    }
    func copy()->Fraction{
        return Fraction(a: self.a)
    }
    }
    class XXXclass{
        class func A_plusplus(f:Fraction){
            f.a++
       }
    }
    var object = Fraction(a:10)
    print("before run func = " + object.toString())
    XXXclass.A_plusplus(object.copy())
    print("after ran func =" + object.toString() )
    
    func add(inout input:Int){
        input++
    }
    
    var a = 10
    print(a)//10
    add(&a)
    print(a)//11
    
    class Person {
        var name: String
        init(name: String) { self.name = name }
    }
    
    var me = Person(name: "Lennon") // Must be var to be passed as inout
    
    // Normal object by reference with a var
    func normalCall(var p: Person) {
        // We sure are able to update p's properties,
        // and they will be reflected back to me
        p.name = "McCartney"
        // Now p points to a new object different from me,
        // changes won't be reflected back to me
        p = Person(name: "Ringo")
    }
    
    // Inout object reference by value
    func inoutCall(inout p: Person) {
        // We still can update p's properties,
        p.name = "McCartney"
        // p is an alias to me, updates made will persist to me
        p = Person(name: "Ringo")
    }
    
    print("\(me.name)") //--> Lennon
    
    normalCall(me)
    print("\(me.name)") //--> McCartney
    
    inoutCall(&me)
    print("\(me.name)") //--> Ringo