我已经使用 Swift 编程几个月了。最近,我更关注 Swift 作为一种语言如何工作的概念。
于是,最近在看apple documentation on Automatic Reference Counting(ARC) ,我遇到了以下几行:
这个在上面:
In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.
在下一段中,以下内容:
To make this possible, whenever you assign a class instance to a property, constant, or variable, that property, constant, or variable makes a strong reference to the instance. The reference is called a “strong“ reference because it keeps a firm hold on that instance, and does not allow it to be deallocated for as long as that strong reference remains.
我对情况的动态有点困惑。我在使用 Storyboard 时注意到,您将引用设置为弱,因此该类看起来像这样,也就是我所说的情况 1:
案例一
class SomeClass : UIViewController {
@IBOutlet weak var nameLabel : UILabel!
override func viewDidLoad() {
nameLabel.text = "something."
}
}
这里,label 与 ViewController 有一对一的弱引用,一旦 Controller 改变,引用就会被破坏(内存释放),因为它是弱引用。因此,没有与内存相关的问题。
如果上述陈述有误或不严谨,请见谅。如果有人证实或反驳我的假设,我会很高兴。
我的问题是关于第二种情况,我不使用 Storyboard,类如下所示:
案例二
class SomeClass : UIViewController {
var nameLabel : UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
view.addSubView(nameLabel)
// view.addConstraints...
}
}
对于上述情况,我的假设是 ViewController 与标签具有一对一的强引用,并且 ViewController 内部的 View 也与标签具有强引用。如果类更改/标签从中删除subview.. 那么我认为内存不会被释放。或者至少 View Controller 将保持对标签的强引用(根据文档。)
我通过从 View 的 subview 中删除标签并打印出标签来确认这一点(它给了我一个 UILabel 的实例,其框架为 0 原点和 0 大小。)因此实例不是 nil。
我唯一能从中收集到的是,虽然标签已从 UIView 中删除,但它仍然保持与 Controller 的强引用,因此内存中的永久状态。我说得对吗?
如果是这样的话。我应该如何防止我的代码出现此类内存问题?更大的问题是,如果我这样声明我的变量,我在将它添加为 Controller 中主视图的 subview 时得到一个 nil。
weak var nameLabel : UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
如果像第二种情况那样声明变量会导致永久性强引用,我应该如何声明它们而不是内存问题?
总而言之,我的问题是:
如果没有使用 Storyboard导出,并且变量被强引用到 View Controller ,这些引用会导致内存问题吗?
如果是这样,我必须遵循哪些代码声明实践?
如果不是这样,请提供深思熟虑的论据和有效的解释来反驳它。
再一次,如果我有任何不正确的地方,请原谅我。
提前致谢。
最佳答案
The only thing I could gather from this was that although the label was removed from UIView, it still maintained a strong reference with the controller, hence permanent state in memory. Am I right?
没有。这里没有什么大问题。
标签没有对 View Controller 的强引用——如果有,那将是一个保留循环,并会导致标签和 View Controller 都泄漏。正是出于这个原因, View 应该永远保持对其 View Controller 的强引用。
然而,这里的情况正好相反: View Controller 对标签有强引用。没关系。确实,标签在从其父 View 中删除后仍然存在。但这可能还不错。在很多情况下,这很好!例如,假设您打算稍后将标签放回界面;您将需要保留它。
如果您确定以后不需要保留标签,那么只需使用一个 Optional 包装一个 UILabel 作为您的实例属性。这样,您可以在使用完后将 nil 分配给标签实例属性,标签将不复存在。
但无论如何这里没有泄漏,你应该不用担心了。当 View Controller 不存在时,标签也将不存在。标签的生命周期比它必须的要长,但从大范围来看,这微不足道且不重要。
关于ios - 强引用变量可能会导致内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38346064/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下