Xcode Swift 2 变量声明(实例成员不能在类型视图控制器上使用)

Posted

技术标签:

【中文标题】Xcode Swift 2 变量声明(实例成员不能在类型视图控制器上使用)【英文标题】:Xcode Swift 2 Variable Declaration (Instance Member cannot be used on type view controller) 【发布时间】:2016-02-15 13:35:23 【问题描述】:

我正在开发一个项目,该项目使用用户在文本字段中定义的 IP 地址发送一些 HTTP 命令。 IP 地址本质上是通过管道传输到我的应用程序的许多不同功能中的。当我这样做时,我一直遇到“实例成员不能用于类型”错误。在变量声明的基础上,执行以下操作的正确方法是什么?我将有大约 40-50 个不同的请求。

@IBOutlet weak var myIPaddress: UITextField!
var baserequest = "http://\(myIPaddress):8088/api/?function="
var requestA = "\(baserequest)myFunctionA&value=abc"
var requestB = "\(baserequest)myFunctionB&value=xyz"
var requestC = "\(baserequest)myFunctionC&value=123"
...
...

我不确定这是否重要,但因为我们使用的是 HTTP 命令,所以其中一个声明看起来像这样

var program1 = NSMutableURLRequest(URL: NSURL(string: "\(baseRequest)activeinput&input=1" )!)

* 更新 *

我不确定我的问题是什么。这是我拥有的代码,它仍然抛出该错误。开

var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!)

这是我的全部代码

import UIKit
import Foundation


func httpGet(request: NSURLRequest!, callback: (String?, NSError?) -> Void) 
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)  data, response, error in
    guard error == nil && data != nil else 
        callback("", error)
        return
    

    callback(String(data: data!, encoding: NSUTF8StringEncoding), nil)

task.resume()


class FirstViewController: UIViewController, UITextFieldDelegate 

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.




@IBOutlet weak var vmixip: UITextField!
var baserequest: String = ""

func textFieldDidEndEditing(textField: UITextField) 
    updateBaseRequest(textField.text!)


func updateBaseRequest(vmixip: String) 
    baserequest = "http://\(vmixip):8088/api/?function="


var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!)
@IBAction func Program1(sender: UIButton) 
    if let image = UIImage(named:"g1") 
        sender.setImage(image, forState: .Normal)
    
    httpGet(request1)  string, error in
        guard error == nil && string != nil else 
            print(error?.localizedDescription)
            return
        

        print(string!) //
    





【问题讨论】:

你究竟是从哪里得到这个错误的? 您有几个问题,1,您需要参考myIPaddress.text 来获取文本字段中的字符串,但更重要的是,您此时无论如何都不能使用该值,因为当用户更改字段时,您将结束更新 baseRequest 和所有其他变量,因此您需要在 UiTextFieldDelegate 之类的代码中编写代码来执行此操作 嗨赛斯。您会考虑对您收到的任何答案进行投票,和/或接受其中一个吗?这就是我们在这里奖励有用答案的方式。 【参考方案1】:

您应该在获得用户 IP 地址后在函数中初始化请求变量。错误是试图告诉你变量的默认值can't something that hasn't been initialized yet(myIPaddress)。

类似:

@IBAction func addressEntered(sender: UIButton) 
    // NOTE: Use myIPaddress.text to get the text
    baserequest = "http://\(myIPaddress.text):8088/api/?function="
    requestA = "\(baserequest)myFunctionA&value=abc"
    requestB = "\(baserequest)myFunctionB&value=xyz"
    requestC = "\(baserequest)myFunctionC&value=123"

此外,如果您在整个类中都需要这些变量,则需要将它们声明为可选项:

class MyClass 
    var requestA: String?
    ...

或者,您可以将请求变量转换为computed properties:

class MyClass 
    var baseRequest: String?
    var requestA: String 
        // Beware, this would crash if used before baseRequest was initialized
        return "\(baseRequest!)myFunctionA&value=abc"
    

【讨论】:

【参考方案2】:

“Instance member cannot be used on type”错误是由引用尚不可用的值引起的。

例如,你不能拥有

var myValue = "something"

然后在

中再次引用该值
var myValueAgain = self.myValue

属性的初始化不像函数中的代码那样工作。这是因为在创建对象之前“self”不可用。您正在尝试在“self”可用之前访问它。


另一个问题是你在

中引用了一个 UITextField
var baserequest = "http://\(myIPaddress):8088/api/?function="

而您可以使用的 String 类型的值在

myIPaddress.text

在初始化时分配值也不会自动更新值,因为它在您的 UI 中发生变化。

处理文本字段的变化需要实现UITextFieldDelegate等方法

textFieldDidBeginEditing: textFieldDidEndEditing:

当用户更新文本字段中的文本时,您使用这些方法来更新您的基本请求。

因此,你的班级会有这样的东西

class MyViewController: UIViewController, UITextFieldDelegate 

    var baserequest: String

    func textFieldDidEndEditing(textField: UITextField) 
        updateBaseRequest(textField.text)
    

    func updateBaseRequest(ipAddress: String) 
        baserequest = "\(ipAddress)..."
    

【讨论】:

对不起,我不确定我在这里缺少什么。这是我的代码。 如果您根据请求号或func getRequest(requestNumber: Int) -> String 之类的内容创建一个函数来获取您的请求,那么您将避免无法使用实例成员的问题。您需要删除 var request1 = NSMutableURLRequest(URL: NSURL(string: "\(baserequest)activeinput&input=1" )!) 以清除错误。我的建议是用函数替换它。每次需要获取 URL 时,都会使用该函数。 @SethHaberman 我已经更新了我的答案,以更好地解释正在发生的事情。让我知道这是否有帮助。

以上是关于Xcode Swift 2 变量声明(实例成员不能在类型视图控制器上使用)的主要内容,如果未能解决你的问题,请参考以下文章

Swift:实例成员不能用于 ARKitVision 示例中的类型

Swift 3 - 实例化视图控制器后没有成员错误

实例成员不能用于 struct swift 之间的嵌套类型的实例

在 Swift 3 中将类与同名的实例成员区分开来

Swift 2 实例成员“circleIndexes”不能用于“GameScene”类型

Swift 属性