泄漏是 Root Leak ,在这个图像中是在同一行上多次引起的,但是下面还有另一个叫做单次,并且还会产生泄漏。
这是调用前面所述代码行之后的调用堆栈。
这是仪器泄漏所在的类:
- (IBAction)share:(id)sender
{
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:0 inSection:0];
[_collectionView insertItemsAtIndexPaths:@[newIndexPath]];
NSArray *selectedIndexPaths = [_collectionView indexPathsForSelectedItems];
NSMutableArray *selectedTexts = [NSMutableArray array];
for (NSIndexPath *indexPath in selectedIndexPaths) {
NSArray *section = videoArray[indexPath.section];
NSString *text = section[indexPath.row];
[selectedTexts addObject:text];
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:text];
[self presentViewController:tweetSheet animated:YES completion:nil];
NSLog(@"%@", text);
}
// NSLog(@"The share works fine");
}
在包含class Item {
var id: String!
var name: String!
internal init(name: String) {
self.name = name
self.id = name
}
var description: String {
return "(\(id)) \(name)"
}
}
的计算变量描述的行中检测到泄漏,并在将描述更改为:
return "(\(id)) \(name)"
更新
或
var description: String {
return "(" + id + ") " + name
}
最后一个发出"字符串来自' String!' to String总是成功"。
所以,即使这看起来像是黑客。
为什么会导致泄漏?
答案 0 :(得分:9)
我测试了你的代码并经历了几个线程,我的理解是你必须使用可选的绑定if let
子句,当使用字符串插值而不是直接使用可选变量时。对于字符串连接,如果我们直接使用选项,则没有问题。问题在于插值。
var description: String {
if let id = self.id, let name = self.name {
return "(\(id)) \(name)"
}
return "NO AVAILABLE DESCRIPTION"
}
您可以在此处获得更多信息memory leak in Swift String interpolation。 看起来像一个错误,可能在将来的版本中它将被解决。
答案 1 :(得分:1)
我实际上更喜欢Hugo与他的问题一起发布的解决方案,因为代码看起来更清晰。在分析我自己的代码之后,我还发现在使用字符串连接后我的内存泄漏得到了解决:
var description: String {
return "(" + id + ") " + name
}
对于它的价值,这篇文章(http://www.globalnerdy.com/2016/02/03/concatenating-strings-in-swift-which-way-is-faster/)也说明在Swift中使用字符串连接要快得多。