【新サービス告知】いつでもどこでもイベントを開催できる。スマホのWebカメラを利用したVRイベントスペースサービス(Meetatcube.com)
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > UnmanagedとUnSafePointer

UnmanagedからUnSafePointer移管によるpassRetainedエラー対応

悩まされ続けております。CoreTextで文字を縦書きにしたいのですがSwift2のコードを3に移管する際にUnmanaged CFStringRefでつまづきました。 解決するまでの流れを記載します。

サンプル画像

参考:UnsafeRawPointer Migration
参考:swift3 で UnsafePointer
参考:https://swift.org/migration-guide/se-0107-migrate.html
参考:ルビを振る
参考:How to use CTRubyAnnotationRef in Swift
参考:How to convert Unmanaged to Swift 3
参考:swift3 で UnsafePointer
参考:インスタンスをUnsafeMutablePointerに変換して扱う
参考:How to use CTRubyAnnotationRef in Swift
参考:lingochamp/FuriganaTextView

やってみた

以下が問題のコンパイルエラーの行。↓以下はSwift2の箇所。


var text = [.passRetained(ruby) as Unmanaged?, .None, .None, .None]
let annotation = CTRubyAnnotationCreate(.Auto, .Auto, 0.5, &text)

↓Swift3の自動変換によって以下に変換されましたがエラーが保持されている状態(UnmanagedがUnsafePointerに変換されていますが、 passRetainedがメンバ関数に無いですとのエラー)


var text = [.passRetained(ruby) as UnSafePointer?, .None, .None, .None]
let annotation = CTRubyAnnotationCreate(.Auto, .Auto, 0.5, &text)

passRetainedとは一体何なのか?

Appleの公式サイトには、Creates an unmanaged reference with an unbalanced retain. と記載されている。アンバランスのretainでマネージされていない参照を作成する。はて、、、わからん。

どうやら retainは「保持」の意味でありObjectiveCでもでていた安全面での記載。Apple公式サイトの下の方にはインスタンスは漏れ出す可能性が あるとのことですので、Swift以外の参照を利用した「部外者」的なものでSwiftが管理しきれないデータを取り出す為の 参照ポイントを作りだす。といったところとの認識です。


参考:passRetained(_:)

履歴

↓Swift3の自動変換によって以下に変換されましたがエラーが保持されている状態(UnmanagedがUnsafePointerに変換されていますが、 passRetainedがメンバ関数に無いですとのエラー)


var text = [Unmanaged.passRetained(ruby) as UnsafeMutablePointer, .None, .None, .None]
let annotation = CTRubyAnnotationCreate(.Auto, .Auto, 0.5, &text)

このようにすると、Cannot convert call result type 'Unmanaged<_>' to expected type 'UnsafeMutablePointer<_>' のエラー。。。。

サンプル画像



要は文字列NSStringのポインタをUnmangedのものを渡せばよいので、、、、


	   
	   var text = [Unmanaged.passUnretained(ruby as CFString).toOpaque(), .None, .None, .None]
                        let annotation = CTRubyAnnotationCreate(.Auto, .Auto, 0.5, &text)
	

↑この上のtoOpaqueはこのインスタンスをUnSafeMutableRawPointerにする。でもまだダメだ。。。

格闘の結果、、、、


このサイトを元に作業How to use CTRubyAnnotationRef in Swift
		
	   let kanji = (x as NSString).substring(with: pair.rangeAt(1))
       let hiragana = (x as NSString).substring(with: pair.rangeAt(2)) as CFString;
       let furigana: UnsafeMutablePointer<Unmanaged<CFString>>! = UnsafeMutablePointer<Unmanaged<CFString>>.allocate(capacity:4)
       furigana[0] = Unmanaged.passUnretained(hiragana)
       let annotation: CTRubyAnnotation = CTRubyAnnotationCreate(CTRubyAlignment.auto, CTRubyOverhang.auto, 0.5, furigana)
		

ひとまずこれでコンパイルエラーが消えた。が確認できていないので再度進捗はアップしていく。サンプルではfurigana[1-3]をnullで初期化していたが 方法がわからず、何もセットしない、で処理している。


追記。やっぱり解決できていない。2017年2月17日

このコードでコンパイルは通るようになったがやはりエラー(CTFramesetterCreateWithAttributedString時にNSExceptionの エラーが)が発生している。対処のメモを残しておきます。Objective C の関数で対応したメモがあった。

	2017-02-17 05:46:39.428 testSwift3[970:17985] -[NSNull length]: unrecognized selector sent to instance 0x1097ad130
2017-02-17 05:46:39.435 testSwift3[970:17985] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x1097ad130'
	

参考:Unsafe Swift: Using Pointers And Interacting With C
参考:クックパッド開発者ブログ
参考:Swift UITextViewにて単語の上にルビを付ける方法

最終落ち着いたのは以下です。

			let kanji = (x as NSString).substring(with: pair.rangeAt(1))
			let furigana = (x as NSString).substring(with: pair.rangeAt(2))
                        
			var text: [Unmanaged?] = [Unmanaged.passRetained(furigana as CFString) as Unmanaged, .none, .none, .none]
			let annotation = CTRubyAnnotationCreate(.auto, .auto, 0.5, &text[0]!)
                        
			return NSAttributedString(
				string: kanji,
				attributes: [kCTRubyAnnotationAttributeName as String: annotation])
							
		

まとめ

紆余曲折してやっと落ち着きました。。。

↓こんな記事もありますよ!


2021-04-22 14:54:53

かっこいいカルーセル厳選3点!WebGLを使った渋い画像スライダー。

昨日カッコいいスライダーを探す旅にでていました。 よく使われるswiper など、シンプルで使いやすくデザインも良いのですが、何かもの足りない、、、。 そこで調べていくと、webglを使...

2021-04-20 14:46:43

Twillioとは何??skywayとは何が違うのか。webrtcを使う際に判断する情報。

先日webrtc開発で「twillio」といった名前を聞きました。 以前自分でskywayを使ってwebrtcを試していた際に調べた時には、無かったような気もするんだけと、KDDIが絡んでいる...

2021-04-19 13:58:21

先日久々にアップデートした妊娠週刊パパのAndroid版も。アカウント移管したいんだけど、注文ID見当たらないよ。

先日の妊娠、出産、育児関連のアプリ「妊娠週刊パパ」をAndroid studioで再リリースしようと思ってるんだけど、コンパイル失敗してエミュレータで動かせない。 多分sdkとかapiのバージ...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!