Xcode 中的 CIContext 内存泄漏问题 swift 中的 9
CIContext Memory Leak issue in Xcode 9 in swift
使用 CIContext.createCGImgage
时,我在 Xcode 9.when 从相机拍摄图像时遇到内存泄漏问题,它占用了更多内存,然后应用程序崩溃了
这是我的代码,
let ciContext = CIContext()
func callFillter() {
let coreImage = CIImage(image: self.appDelegate.selectPic)
for i in 0..<CIFilterNames.count {
itemCount = i
if self.originalImage.image != nil{
autoreleasepool() {
print("originalimage\(self.originalImage)")
self.imageToFilter.image = self.originalImage.image!
print("originalImage\(self.imageToFilter.image!)")
print("coreImage\(coreImage)")
let filter = CIFilter(name: "\(CIFilterNames[i])" )
filter!.setDefaults()
filter!.setValue(coreImage, forKey: kCIInputImageKey)
let filteredImageData = filter!.value(forKey: kCIOutputImageKey) as! CIImage
if let output = filter?.outputImage {
ciContext.clearCaches()
autoreleasepool(){
let filteredImageRef = ciContext.createCGImage_(image: output, fromRect: filteredImageData.extent)
var filterButton = UIButton(type: .custom)
filterButton.frame = CGRect(x: self.xCoord, y: self.yCoord, width: self.buttonWidth, height: self.buttonHeight)
filterButton.tag = self.itemCount
filterButton.showsTouchWhenHighlighted = true
filterButton.addTarget(self, action: #selector(self.filterButtonTapped(_:)), for: .touchUpInside)
filterButton.layer.cornerRadius = 6
filterButton.clipsToBounds = true
let imageForButton = UIImage(cgImage: filteredImageRef)
filterButton.setBackgroundImage(imageForButton, for: UIControlState())
self.xCoord += self.buttonWidth + self.gapBetweenButtons
self.filtersScrollView.addSubview(filterButton)
}
}
}
print("itemCount \(itemCount)")
filtersScrollView.contentSize = CGSize(width: (buttonWidth + 5) * CGFloat(itemCount + 1), height: yCoord)
}
和从
调用的函数
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
}
这会占用大量内存并且应用会崩溃。
作为答案发布,因为我查看了您的代码和"get"您正在尝试做的事情。
您的代码有一些问题 - 但 主要 问题是您每次调用此函数时都会创建一个 CIContext
。将该上下文移出您的函数 - 使其更具全局性 - 您不仅会看到更好的内存使用率,还会看到更好的性能。
其次,您似乎正在创建应用于单个图像的各种滤镜的滚动视图。基于此,为什么不去掉 autoreleasepool()
和 ciContext.clearCaches()
?这些并没有真正完成任何事情。
因为 Swift(默认情况下)将只读参数传递给函数,为什么不添加 CIImage
(或者 UIImage
)作为参数来使您的代码更易于使用和调试?
最后,您在 for i in 0..<CIFilterNames.count
循环并在该循环中做 很多。把那个代码拉出来。使它成为一个函数。它可能有助于找出内存泄漏。
**同样,我敢打赌,它会在该循环中为 每次迭代 创建一个 CIContext
是原因。将其移出并编写代码以使用单个上下文 - 不仅针对该循环中的每次迭代,而且针对 callFillter()
.
的每次调用
使用 CIContext.createCGImgage
时,我在 Xcode 9.when 从相机拍摄图像时遇到内存泄漏问题,它占用了更多内存,然后应用程序崩溃了
这是我的代码,
let ciContext = CIContext()
func callFillter() {
let coreImage = CIImage(image: self.appDelegate.selectPic)
for i in 0..<CIFilterNames.count {
itemCount = i
if self.originalImage.image != nil{
autoreleasepool() {
print("originalimage\(self.originalImage)")
self.imageToFilter.image = self.originalImage.image!
print("originalImage\(self.imageToFilter.image!)")
print("coreImage\(coreImage)")
let filter = CIFilter(name: "\(CIFilterNames[i])" )
filter!.setDefaults()
filter!.setValue(coreImage, forKey: kCIInputImageKey)
let filteredImageData = filter!.value(forKey: kCIOutputImageKey) as! CIImage
if let output = filter?.outputImage {
ciContext.clearCaches()
autoreleasepool(){
let filteredImageRef = ciContext.createCGImage_(image: output, fromRect: filteredImageData.extent)
var filterButton = UIButton(type: .custom)
filterButton.frame = CGRect(x: self.xCoord, y: self.yCoord, width: self.buttonWidth, height: self.buttonHeight)
filterButton.tag = self.itemCount
filterButton.showsTouchWhenHighlighted = true
filterButton.addTarget(self, action: #selector(self.filterButtonTapped(_:)), for: .touchUpInside)
filterButton.layer.cornerRadius = 6
filterButton.clipsToBounds = true
let imageForButton = UIImage(cgImage: filteredImageRef)
filterButton.setBackgroundImage(imageForButton, for: UIControlState())
self.xCoord += self.buttonWidth + self.gapBetweenButtons
self.filtersScrollView.addSubview(filterButton)
}
}
}
print("itemCount \(itemCount)")
filtersScrollView.contentSize = CGSize(width: (buttonWidth + 5) * CGFloat(itemCount + 1), height: yCoord)
}
和从
调用的函数func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
}
这会占用大量内存并且应用会崩溃。
作为答案发布,因为我查看了您的代码和"get"您正在尝试做的事情。
您的代码有一些问题 - 但 主要 问题是您每次调用此函数时都会创建一个 CIContext
。将该上下文移出您的函数 - 使其更具全局性 - 您不仅会看到更好的内存使用率,还会看到更好的性能。
其次,您似乎正在创建应用于单个图像的各种滤镜的滚动视图。基于此,为什么不去掉 autoreleasepool()
和 ciContext.clearCaches()
?这些并没有真正完成任何事情。
因为 Swift(默认情况下)将只读参数传递给函数,为什么不添加 CIImage
(或者 UIImage
)作为参数来使您的代码更易于使用和调试?
最后,您在 for i in 0..<CIFilterNames.count
循环并在该循环中做 很多。把那个代码拉出来。使它成为一个函数。它可能有助于找出内存泄漏。
**同样,我敢打赌,它会在该循环中为 每次迭代 创建一个 CIContext
是原因。将其移出并编写代码以使用单个上下文 - 不仅针对该循环中的每次迭代,而且针对 callFillter()
.