我有一个View Controller和两个类。 ClassOne和ClassTwo都引用了视图控制器,如下所示:
var viewController: ViewController?
视图控制器和ClassTwo都有一个ClassOne
变量,我已按此分配,以便检索其他变量和调用函数。
let class_one = ClassOne()
在ClassOne
中,我试图在ClassTwo中调用一个函数,该函数使用class_one
来调用ClassOne中的函数。例如,在ClassTwo中:
func changeString() {
self.class_one.string = "yada yada"
}
以下是我尝试在changeString()
中致电ClassOne
的不同方式:
// Method one:
ClassTwo().changeString()
// Method two:
let class_two = ClassTwo()
self.class_two.changeString()
// Method three:
var class_two: ClassTwo?
self.class_two!.changeString()
当我使用方法一运行应用程序时,应用程序崩溃并说ClassTwo
中的viewController和classOne引用为零。
当我使用方法2运行应用程序时,它会崩溃并且Xcode会给我以下内存警告,引用changeString()
中的ClassOne
函数调用和self.class_one.string
之间的来回错误ClassTwo
中的变量调用。
Xcode memory warning - could not load any Objective-C class information
这不是我的实际代码,但这是我面临的问题。我是Swift的初学者,我真的不明白来自ClassTwo
的所有三个ClassOne
函数调用的区别。
有人可以解释一下我做错了吗?
答案 0 :(得分:0)
老实说,根据您提供的信息确定崩溃的原因是不可能的。您必须更详细地发布实际代码,而不是在此处。
这是一个答案的原因是因为你的场景很糟糕。听起来您可以从划分代码中受益。
实施例
如果您有一个负责跟踪用户位置的类,您可以在视图控制器中实例化它,如下所示:
let locationTracker = LocationTracker()
然后我们假设你需要将位置值解析为一个字符串,你可能有另一个类负责这个:
let locationParser = LocationParser()
这里有无原因,locationParser
和locationTracker
可以相互引用 OR 视图控制器,例如
let location = locationTracker.currentLocation()
let locationAsString = locationParser.parseLocation(location)
全球职能
我毫不犹豫地添加它,因为它可能导致无法维护和无组织的代码,但是在swift中你可以在类之外定义一个函数。类中的函数通常称为方法。当他们在课堂外时,他们被称为功能。
所以你可以有一个名为Functions.swift
的快速文件,只需定义:
func globalFunc() {
print("Hello, World!")
}
可以从代码中的任何位置调用此函数。
代码设计
如果您想要创建可维护且质量非常高的软件,那么构建和设计代码的方式非常重要。
您可以通过阅读不同的架构和工具来帮助您组织项目。像:
MVC是Apple的方式,但您可以从其他方法的知识中受益。另请注意,依赖注入文章提供了Objective-C
代码示例。我知道你正在学习斯威夫特,但如果可以的话,掌握Objective-C
的工作知识会更好。 Apple的框架仍然全部用Objective-C
编写。
答案 1 :(得分:0)
看起来你正在使用委托模型,在这种情况下,我认为你的选项会走向错误的方向。您可能希望ClassOne
肯定有一个ViewController
,它可以根据需要进行操作。代理总是控制某个对象,因此ClassOne
应该有var viewController: ViewController
。不是每个ViewController
都需要一个委托 - 至少,有一个没有委托的ViewController
是有意义的(即使结果是一个糟糕的视图控制器),而没有{{1}的委托管理是无稽之谈 - 所以ViewController
应该有ViewController
。您没有在初始化中分配var class_one: ClassOne? = nil
因为您需要在class_one
可能存在之前存在视图控制器。因此,在初始化视图控制器后设置ClassOne
。
我认为这可以通过解决一些内部依赖来解决您的问题。此外,改变也不会太长。