質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

2407閲覧

CGDataProviderReleaseDataCallbackが呼ばれない

退会済みユーザー

退会済みユーザー

総合スコア0

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2017/06/04 12:00

###前提・実現したいこと
CGDataProviderReleaseDataCallbackが呼ばれるようにしたい。
referanceの読み方がわかればできるのかもしれませんが、理解できておりません。。

###発生している問題・エラーメッセージ
CGDataProviderReleaseDataCallback が呼ばれないため?実機テスト時の処理が固まる。

###該当のソースコード

import UIKit import CoreImage class TransparentImage: NSObject { func transparentImage (image: UIImage) -> UIImage{ //画面に表示されたものと同じ画像が渡ってくる。拡大、縮小されていればその画像。 var editedimage:UIImage //あとでletに変える let width :Int = Int((image.cgImage!.width)) let height :Int = Int((image.cgImage!.height)) let imageData = image.cgImage!.dataProvider!.data //cgimageのデータ let datalenght = CFDataGetLength(imageData) var rawData = [UInt8](repeating: 0, count: datalenght) CFDataGetBytes(imageData,CFRange(location: 0, length: datalenght),&rawData) //画像データをrawDataへ転送 print("画像のdatalengthの長さ\(datalenght)") print("初期画像のサイズ cgimage width:\(width)") print("初期画像のサイズ cgimage height:\(height)") print("初期画像のサイズ uiimage width:\(image.size.width)") print("初期画像のサイズ uiimage width:\(image.size.height)") print("AlphaInfo:\(image.cgImage!.alphaInfo.rawValue)") print("scale:\(image.scale)") // ###画像の生成### let provider = CGDataProvider(dataInfo: nil,data: rawData, size: datalenght,releaseData: releaseData) let colorSpaceRef = image.cgImage!.colorSpace let bitmapInfo = image.cgImage!.bitmapInfo let bitsPerComponent:Int = image.cgImage!.bitsPerComponent let bitsPerPixel = image.cgImage!.bitsPerPixel let bytesPerRow = image.cgImage!.bytesPerRow let cgImage = CGImage(width: width, height: height, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow:bytesPerRow, space: colorSpaceRef!, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent) editedimage = UIImage(cgImage:cgImage!, scale:image.scale, orientation:image.imageOrientation) // print ("colorSpaceRef:\(colorSpaceRef)") print("bitmapInfo:\(bitmapInfo)") print("加工後画像幅:\(editedimage.size.width)") print("加工後画像高さ:\(editedimage.size.height)") print("bitsPerComponent:\(bitsPerComponent)") print("bitsPerPixel:\(bitsPerPixel)") print("bytesPerRow:\(bytesPerRow)") return editedimage } let releaseData: CGDataProviderReleaseDataCallback = { (info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size: Int) -> () in // https://developer.apple.com/reference/coregraphics/cgdataproviderreleasedatacallback print("callback") return }

###補足情報(言語/FW/ツール等のバージョンなど)
swift3 iPhone7Plus

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

CGDataProviderは、使い終わったらプログラマーが明示的に解放の指示を出さないと解放されないようです。生成したプロバイダが解放されないために、解放時に呼ばれるコールバックがいつまでも呼ばれないままになっているのかもしれません。
リファレンスには、下記のような記述があります。

init(dataInfo:data:size:releaseData:) - CGDataProvider | Apple Developer Documentation

Return Value
A new data provider. You are responsible for releasing this object using CGDataProviderRelease.

返値
新しいデータプロバイダ。あなたはCGDataProviderReleaseを用いてこのオブジェクトを解放する責任があります。

[追記]
失礼しました、CGDataProviderの解放も自動的に面倒を見てくれるようですね。ろくに確認せず投稿したのはまずかったです。
というわけで少し試したのですが、私の環境ですと、少なくともシミュレータではコールバックは呼ばれるようでした。申し訳ないですが実機テストはちょっとしたトラブルのため試せませんでした(「実機テスト時の処理が固まる」ということは、シミュレータでは正しくコールバックが呼ばれるのでしょうか)。
以下のようなコードで試しました。

###ViewController.swift
viewDidAppearで加工後画像を生成して加工後用のイメージビューにセットし、削除ボタン押下でnilをセットしました。

swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var imageView: UIImageView! 6 @IBOutlet weak var processedImageView: UIImageView! 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 // Do any additional setup after loading the view, typically from a nib. 11 } 12 13 override func viewDidAppear(_ animated: Bool) { 14 let tImage = TransparentImage() 15 if let image = self.imageView.image 16 { 17 let processedImage = tImage.transparentImage(image: image) 18 self.processedImageView.image = processedImage 19 } 20 } 21 22 override func didReceiveMemoryWarning() { 23 super.didReceiveMemoryWarning() 24 // Dispose of any resources that can be recreated. 25 } 26 27 @IBAction func deleteImage(_ sender: UIButton) { 28 self.processedImageView.image = nil 29 print("加工後画像を削除") 30 } 31 32}

###TransparentImage.swift
質問者さんご提示のものとほとんど同じですが、// print ("colorSpaceRef:\(colorSpaceRef)")print("colorSpaceRef:\(String(describing: colorSpaceRef?.name))")にして、念のためカラースペースも表示させてみました。

swift

1import UIKit 2 3class TransparentImage: NSObject { 4 func transparentImage (image: UIImage) -> UIImage{ 5 6 //画面に表示されたものと同じ画像が渡ってくる。拡大、縮小されていればその画像。 7 var editedimage:UIImage //あとでletに変える 8 let width :Int = Int((image.cgImage!.width)) 9 let height :Int = Int((image.cgImage!.height)) 10 let imageData = image.cgImage!.dataProvider!.data //cgimageのデータ 11 let datalenght = CFDataGetLength(imageData) 12 var rawData = [UInt8](repeating: 0, count: datalenght) 13 CFDataGetBytes(imageData,CFRange(location: 0, length: datalenght),&rawData) //画像データをrawDataへ転送 14 print("画像のdatalengthの長さ\(datalenght)") 15 print("初期画像のサイズ cgimage width:\(width)") 16 print("初期画像のサイズ cgimage height:\(height)") 17 print("初期画像のサイズ uiimage width:\(image.size.width)") 18 print("初期画像のサイズ uiimage width:\(image.size.height)") 19 print("AlphaInfo:\(image.cgImage!.alphaInfo.rawValue)") 20 print("scale:\(image.scale)") 21 22 // ###画像の生成### 23 let provider = CGDataProvider(dataInfo: nil,data: rawData, size: datalenght,releaseData: releaseData) 24 let colorSpaceRef = image.cgImage!.colorSpace 25 let bitmapInfo = image.cgImage!.bitmapInfo 26 let bitsPerComponent:Int = image.cgImage!.bitsPerComponent 27 let bitsPerPixel = image.cgImage!.bitsPerPixel 28 let bytesPerRow = image.cgImage!.bytesPerRow 29 let cgImage = CGImage(width: width, height: height, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow:bytesPerRow, space: colorSpaceRef!, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent) 30 editedimage = UIImage(cgImage:cgImage!, scale:image.scale, orientation:image.imageOrientation) 31 print("colorSpaceRef:\(String(describing: colorSpaceRef?.name))") 32 print("bitmapInfo:\(bitmapInfo)") 33 print("加工後画像幅:\(editedimage.size.width)") 34 print("加工後画像高さ:\(editedimage.size.height)") 35 print("bitsPerComponent:\(bitsPerComponent)") 36 print("bitsPerPixel:\(bitsPerPixel)") 37 print("bytesPerRow:\(bytesPerRow)") 38 39 40 return editedimage 41 } 42 43 let releaseData: CGDataProviderReleaseDataCallback = { (info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size: Int) -> () in 44 // https://developer.apple.com/reference/coregraphics/cgdataproviderreleasedatacallback 45 print("callback") 46 return 47 } 48}

###Main.storyboard
イメージビュー2枚とボタン1個を下図のように配置しました。
ストーリーボード

###実行時の出力
ムービー

実機テストができるようになりましたら、そちらも試してみようかと思います。

投稿2017/06/05 03:45

編集2017/06/05 19:27
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/05 13:38

ご回答ありがとうございます!こちら追記すると、下記のエラーが出ます。 自動でメモリー解放してくれるようなのです...。 'CGDataProviderRelease' is unavailable: Core Foundation objects are automatically memory managed
退会済みユーザー

退会済みユーザー

2017/06/08 14:40

ありがとうございます、Releaseのタイミングを勘違いしていただけのようです。確かに私のプログラムの方でも呼ばれていました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問