【问题标题】:Swift.... Class method vs. Instance methodSwift .... 类方法与实例方法
【发布时间】:2015-08-27 12:55:44
【问题描述】:

提前感谢您的帮助!

我正在尝试从我的班级中调用一个 func,但我不断收到错误消息:

参数#1 缺少参数.............阅读一些帖子说这是实例与类的问题?我不明白..我在类中调用方法???如果方法被调用,必须有一个类的实例??????正确的?这是我的代码...谢谢

import Foundation
import Parse

class TestViewController {

    let photos = getWallImages() //-----This is the line requesting an argument

    func getWallImages() -> [WallPost] {
        let query = WallPost.query()!
        query.findObjectsInBackgroundWithBlock { objects, error in

            if error == nil {
                if let objects = objects as? [WallPost] {
                    return objects
                    println("We have \(objects.count)")
                }
            } else if let error = error {
                println(error)
            }
        }
    }

}

【问题讨论】:

  • 如果方法不需要类的实例,则在类之外声明函数。在某些语言中,例如 Objective-C,有不需要实例的类方法,Swift 有类似的 Type 方法。请注意,对类实例方法的低级调用传递了一个类实例指针。
  • 澄清因为答案使用不同的关键字来创建类型方法,来自 Apple 文档:“您通过在方法的 func 关键字之前编写关键字 static 来指示类型方法。类也可以使用 class 关键字来允许子类覆盖该方法的超类实现。”

标签: swift


【解决方案1】:

因此,您所犯的“罪行”是该方法应用于类的实例而不是作为类方法。该函数需要一个 self 参数(对实例的引用)。这解释了错误消息。

现在要解决您有两个快速选择的问题:

1. 将其设为类函数并以这种方式调用它:

class TestViewController {
    let photos = TestViewController.getWallImages()

    class func getWallImages() -> [WallPost] {
        // mumbo jumbo
    }
}

如果您想要执行一些特定于实例的操作,这种方法会出现问题,因为class func 是静态方法,不会为您提供一些对象优势。

2.实例化你正在调用方法的对象:

class TestViewController {
    let photos = TestViewController().getWallImages()

    func getWallImages() -> [WallPost] {
        // mumbo jumbo
    }
}

这种方法对您给定的结构不正确 - 实例化 另一个 视图控制器没有意义,但如果您采用该方法并将其放在单独的类中,也许它会那么就有意义了。

当然,您还有多种其他方法可以更改代码以使其正常工作。也许你可以用lazy参数初始化它,也许你可以在init方法中初始化它。什么最适合你。我的回答只是解释你哪里出错了。

【讨论】:

    【解决方案2】:

    有几种方法可以适当地设置您的属性。您可以将getWallImages() 设为类型方法:

    class TestViewController {
    
        let photos = TestViewController.getWallImages()
    
        class func getWallImages() -> [WallPost] {
             ....
        }
    
    }
    

    或者,您可以将您的方法保留为实例方法并在初始化时设置您的属性:

    class TestViewController {
    
        let photos: [WallPost]!
    
        init() {
            super.init()
            photos = getWallImages()
        }
    
        func getWallImages() -> [WallPost] {
             ....
        }
    
    }
    

    【讨论】:

    • 我明白了...谢谢!
    【解决方案3】:

    如果您提出问题,则应将代码减少到最少,丢弃不必要的细节。

    你可能想要这样的东西:

    class MyClass {
        let x = MyClass.getStuff()
    
        static func getStuff() -> Int {
            return 0
        }
    }
    

    但是你的方法getWallImages() 不能做这样的事情,因为它异步返回结果,这意味着你在函数返回后很晚才得到结果。

    你可以做这样的事情(这就是我的做法):

    class MyClass {
        var x : Int? {
            didSet {
                if let x = x {
                    // Do something with x, here it's assigned
                } else {
                    // x was set to nil, something failed
                }
            }
        }
    
        init() {
            getStuffAsynchronous()
        }
    
        func getStuffAsynchronous() {
            // Do your query stuff here, assign x to your objects to invoke the didSet
            x = 0
    
            // If it fails somehow, assign set x to nil
            // if fail {
            //     x = nil
            // }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-22
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-03
      • 2015-08-12
      相关资源
      最近更新 更多