---
title: NS Prefix 外伝 … Copy-On-Write #関モバ
tags:  #関モバ #swift  
author: [熊谷友宏](https://www.docswell.com/user/es_kumagai)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/LJLPQ82PER.jpg?width=480
description: Swift 3 の変化のひとつに Foundation での NS プレフィックス削除があります。その中でも、とりわけ &quot;新しい値型&quot; の新設に伴って、値型とクラス型をブリッジする選択が取られた型の、そのパフォーマンスの最適化に注目してみました。  ※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,693 でした。
published: October 27, 16
canonical: https://www.docswell.com/s/es_kumagai/KMXL9W-copy-on-write-161026175442
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/LJLPQ82PER.jpg)

/41SFGJY֎఻
$PQZ0O8SJUF
ؔ੢ϞόΠϧΞϓϦ‫ڀݚ‬ձ ʜ
&amp;;/&amp;5‫۽‬୩༑޺
IUUQF[OFUKQ
4XJGU


# Page. 2

![Page Image](https://bcdn.docswell.com/page/47M41682EW.jpg)

‫۽‬୩༑޺
5PNPIJSP,VNBHBJ
⾣
4XJGU‫͕ޠݴ‬௒େ޷͖Ͱ͢ʂ
⾣
ΈΜͳͰָ͠Ήษ‫ڧ‬ձ͕େ޷͖Ͱ͢ʂ
⾣
ϓϩάϥϛϯάͷָ͠͞Λ఻͍͖͍͑ͯͨɻ
!FT@LVNBHBJ
UPNPIJSPLVNBHBJ
$PEF1JFDFGPSNBD04
IUUQF[OFUKQ
9DPEFపఈղઆ


# Page. 3

![Page Image](https://bcdn.docswell.com/page/P7RWLP55E9.jpg)

ษ‫ڧ‬ձΛ։࠵͍ͯ͠·͢ɻ
Θ͍Θ͍ɺָ͘͠ɺ
ΈΜͳͰ‫ޠ‬Β͑Δ৔ॴΛ໨ࢦͯ͠
ԣ඿J1IPOF։ൃऀษ‫ڧ‬ձ
ୈճ໨͸݄೔ͷ։࠵
ΧδϡΞϧ4XJGUษ‫ڧ‬ձ
ୈճ໨Λ݄ʹ։࠵ʢ‫ݕ‬౼தʣ
ΈΜͳͰ4XJGU ෮शձ
ୈճ໨Λ݄தʹ։࠵ʢ‫ݕ‬౼தʣ
ZJEFW ˏԣ඿ɾഅंಓ
IUUQTBUOEPSHHSPVQTZJEFW
DTXJGU !ԣ඿ɾ੨༿୆
IUUQTBUOEPSHHSPVQTDTXJGU
NJOOB@EF@TXJGU ˏौ୩
IUUQDTXJGUDPOOQBTTDPN


# Page. 4

![Page Image](https://bcdn.docswell.com/page/PJXPW3KXEX.jpg)

NPPLNPPLSBEJP Ќ൛
ϜοΫϜοΫϥδΦ
‫۽‬୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ಺͔Β
ௌ͑ͯ͘͜Δ੠ʹࣖΛ܏ָ͚ͯ͠ΉϥδΦ
ຖ݄ୈ̎ɾୈ̐ ݄༵೔ ʹ഑৴
IUUQNPPLNPPLSBEJPDPNB
⾣
ୈ̒࿩
ʢ݄೔ʹ഑৴༧ఆʣ
⾣
ୈ̑࿩
ʰΞΫηείϯτϩʔϧʱ
⾣
ୈ̐࿩
ʰίϝϯτͷଓ͖ˍ੔਺‫ܕ‬ʱ
⾣
ୈ̏࿩
ʰίϝϯτʱ
⾣
ୈ̎࿩
ʰྻ‫ܕڍ‬ʱ


# Page. 5

![Page Image](https://bcdn.docswell.com/page/3JKDVY597D.jpg)

%SPQ/41SFGJY
JO4XJGU&#039;PVOEBUJPO


# Page. 6

![Page Image](https://bcdn.docswell.com/page/LE3RM9K975.jpg)

%SPQ/41SFpYJO4XJGU&#039;PVOEBUJPO
/41SFpY
⾣ ফ͑Ώ͘΋ͷ
⾣ ࢒Δ΋ͷ
⾣ ‫ڞ‬ଘ͢Δ΋ͷ


# Page. 7

![Page Image](https://bcdn.docswell.com/page/8EDY6G38EG.jpg)

/41SFpY
‫ڞ‬ଘ͢Δ΋ͷ
⾣ ஋‫ܕ‬૬౰ͷΫϥεͰɺ஋‫৽͕ܕ‬ઃ͞Εͨ΋ͷ
⾣ /4෇͖ͷΫϥε‫ͱܕ‬ɺ/4ͳ͠ͷ஋‫ڞ͕ͱܕ‬ଘ
ͨͱ͑͹ʜ
• NSString, String
• NSData, Data
• NSArray, Array&lt;Element&gt;


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V7P6Y34WJ8.jpg)

/FX7BMVF5ZQFT
JO4XJGU&#039;PVOEBUJPO


# Page. 9

![Page Image](https://bcdn.docswell.com/page/2JV3G4X9EQ.jpg)

/FX7BMVF5ZQFT
஋‫ʹܕ‬૬౰͢ΔΫϥεʹண໨
⾣ ಉ౳ͷ஋‫ܕ‬Λɺߏ଄ମͰ ৽‫ ن‬௥Ճʜ/41SFpYͳ͠
⾣ ‫ط‬ଘͷΫϥε‫ܕ‬͸ɺͦͷ·· ଘଓ ʜ/41SFpY͋Γ
⾣ ஋‫ͱܕ‬Ϋϥε‫ܕ‬Λ૬‫ ʹޓ‬ϒϦοδ
⾣ ஋‫ܕ‬Λओମʹѻ͏͜ͱͰɺ4XJGUͷྑ͞Λಋग़
⾣ ஋‫ͱܕ‬Ϋϥε‫Ͱܕ‬ɺ‫ػ‬ೳ͕΍΍ҟͳΔ৔߹΋͋Δ


# Page. 10

![Page Image](https://bcdn.docswell.com/page/5EG381V47L.jpg)

/FX7BMVF5ZQFT
*NNVUBCMF⁶/4*NNVUBCMF
⾣ ಉ౳ͷߏ଄ମΛ&#039;PVOEBUJPOʹ௥Ճ
⾣ ૒ํͱ΋ɺੑ࣭͸WBS΋MFU΋*NNVUBCMFѻ͍
TUSVDU66*%
DMBTT/466*%


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4JQ59D6R7P.jpg)

/FX7BMVF5ZQFT
.VUBCMF⁶/4.VUBCMF
⾣ ಉ౳ͷߏ଄ମΛ&#039;PVOEBUJPOʹ௥Ճ
⾣ ஋‫Ͱܕ‬͸ɺੑ࣭͕WBS͔MFU͔ͰมԽ
TUSVDU&quot;⒏OF5SBOTGPSN
DMBTT/4&quot;⒏OF5SBOTGPSN
TUSVDU%BUF
DMBTT/4%BUF
TUSVDU%BUF$PNQPOFOUT
DMBTT/4%BUF$PNQPOFOUT
TUSVDU1FSTPO/BNF$PNQPOFOUT
DMBTT/41FSTPO/BNF$PNQPOFOUT
TUSVDU63-
DMBTT/463-
TUSVDU63-$PNQPOFOUT
DMBTT/463-$PNQPOFOUT


# Page. 12

![Page Image](https://bcdn.docswell.com/page/K749XZ4QE1.jpg)

/FX7BMVF5ZQFT
.VUBCMF⁶/4*NNVUBCMF
⾣ ಉ౳ͷߏ଄ମΛ&#039;PVOEBUJPOʹ௥Ճ
⾣ ஋‫͚ͩܕ‬NVUBUJOHͳੑ࣭Λ࣋ͭ
TUSVDU*OEFY1BUI
DMBTT/4*OEFY1BUI
TUSVDU/PUJpDBUJPO
DMBTT/4/PUJpDBUJPO
TUSVDU63-2VFSZ*UFN
DMBTT/463-2VFSZ*UFN


# Page. 13

![Page Image](https://bcdn.docswell.com/page/LJ1KNR4L7G.jpg)

/FX7BMVF5ZQFT
.VUBCMF⁶/4 *NNVUBCMF .VUBCMF
⾣ ஋‫ܕ‬ͷߏ଄ମΛ&#039;PVOEBUJPOʹ௥Ճ
⾣ ஋‫*ͱܕ‬NNVUBCMFΛϒϦοδɺΫϥεؒ͸Ωϟετ
TUSVDU$IBSBDUFS4FU
DMBTT/4$IBSBDUFS4FU
DMBTT/4.VUBCMF$IBSBDUFS4FU
TUSVDU%BUB
DMBTT/4%BUB
DMBTT/4.VUBCMF%BUB
TUSVDU*OEFY4FU
DMBTT/4*OEFY4FU
DMBTT/4.VUBCMF*OEFY4FU


# Page. 14

![Page Image](https://bcdn.docswell.com/page/GJWD41XQ72.jpg)

7BMVF5ZQFT


# Page. 15

![Page Image](https://bcdn.docswell.com/page/4EZG2P63J3.jpg)

7BMVF5ZQFT
஋‫ࢀͱܕ‬র‫ܕ‬
⾣ ஋‫  ܕ‬ʜσʔλΛίϐʔ
⾣ ࢀর‫ ܕ‬ʜΠϯελϯεΛ‫ڞ‬༗


# Page. 16

![Page Image](https://bcdn.docswell.com/page/Y76YVM2ZEV.jpg)

ࠓ·Ͱࢀর‫ͨͬͩܕ‬ͷΛ
஋‫ͯ͠ʹܕ‬ɺॏ͘ͳΒͳ͍ͷʁ


# Page. 17

![Page Image](https://bcdn.docswell.com/page/G75GDZ2974.jpg)

0QUJNJ[BUJPO


# Page. 18

![Page Image](https://bcdn.docswell.com/page/9J2Y8R45JR.jpg)

0QUJNJ[BUJPO
3FGFSFODF$POWFSUJCMF
⾣ Ͳͷࢀর‫ʹܕ‬ϒϦοδͰ͖Δ͔Λද‫ݱ‬
⾣ ϒϦοδର৅ͷࢀর‫ܕ‬͸lίϐʔՄೳzͱ‫ن‬ఆ
// 要所だけ抜粋
protocol ReferenceConvertible
: _ObjectiveCBridgeable {
// 参照型は Objective-C 互換で、コピー可能
associatedtype ReferenceType
: NSObject, NSCopying
}


# Page. 19

![Page Image](https://bcdn.docswell.com/page/DEYG6DM6EM.jpg)

-BSHFS7BMVF5ZQFT


# Page. 20

![Page Image](https://bcdn.docswell.com/page/VJNGZ63178.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
$PQZ0O8SJUF
⾣ ΫϥεΠϯελϯεͷࢀরΛ಺แ͠ɺ‫ڞ‬༗
⾣ ॻ͖ࠐΈ࣌ʹॳΊͯɺσʔλΛෳ੡
஋
8SJUF
Ϋϥε
Ϋϥε
#SJEHF
ʷ
࣮ମ
࣮ମ
$PQZ


# Page. 21

![Page Image](https://bcdn.docswell.com/page/YE9WZL9YE3.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
$PQZ0O8SJUFͷಛ௃
⾣ ίϐʔͷ‫ݪ‬ଇΛӡ༻ͰΧόʔʢ҉໧తʣ
⾣ ඞཁʹͳΔ·Ͱɺσʔλͷෳ੡ίετΛճආ
⾣ ࢀরΧ΢ϯτपΓͷ؅ཧίετ͸૿Ճ


# Page. 22

![Page Image](https://bcdn.docswell.com/page/GE8N1X9K7D.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
-BSHFS7BMVF5ZQFT

$IBSBDUFS4FU

%BUF$PNQPOFOUT

%BUB

*OEFY4FU

*OEFY1BUI

1FSTPO/BNF$PNQPOFOUT

63-

63-$PNQPOFOUT

63-2VFSZ*UFN
 66*%


# Page. 23

![Page Image](https://bcdn.docswell.com/page/LELPQ8WP7R.jpg)

%BUBͷ࣮ࡍ


# Page. 24

![Page Image](https://bcdn.docswell.com/page/4JM416927W.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍ
⾣ /4%BUB΁ͷϒϦοδΛ૝ఆ
⾣ ࢀরΛ@4XJGU/4%BUBͰ#PYJOH
public struct Data
: ReferenceConvertible, _MutablePairBoxing {
// NSData とのブリッジ
public typealias ReferenceType = NSData
// 参照をラップ (Boxing) する
internal var _wrapped : _SwiftNSData


# Page. 25

![Page Image](https://bcdn.docswell.com/page/PJRWLPG579.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍ#PYJOH
⾣ /4%BUBͱ/4.VUBCMF%BUBΛ۠ผͯ͠؅ཧ
⾣ /4%BUBͱϝϞϦϨϕϧͰ‫׵ޓ‬ੑ͕͋ΔΒ͍͠
internal final class _SwiftNSData {
// NSData と NSMutableData とを管理するラッパー
var __wrapped : _MutableUnmanagedWrapper&lt;
NSData, NSMutableData&gt;


# Page. 26

![Page Image](https://bcdn.docswell.com/page/PEXPW3XX7X.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍ#PYJOHৄࡉ
⾣ *NNVUBCMF·ͨ͸.VUBCMFͷͲͪΒ͔
⾣ /PO&quot;3$ͰࢀরΛ؅ཧ
internal enum _MutableUnmanagedWrapper&lt;
ImmutableType, MutableType&gt; {
case Immutable(Unmanaged&lt;ImmutableType&gt;)
case Mutable(Unmanaged&lt;MutableType&gt;)
}


# Page. 27

![Page Image](https://bcdn.docswell.com/page/3EKDVYW9JD.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍΠϯελϯεԽ
⾣ ಺෦σʔλΛɺΫϥε‫ܕ‬ͷࢀরͰ࣋ͭ
⾣ Ұൠʹɺ*NNVUBCMFͳΠϯελϯεͰੜ੒
public init(bytes: UnsafeRawPointer, count: Int) {
_wrapped = _SwiftNSData(immutableObject:
NSData(bytes: bytes, length: count))
}


# Page. 28

![Page Image](https://bcdn.docswell.com/page/L73RM919J5.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍฤू
⾣ *NNVUBCMFͳΒɺແ৚݅ͰNVUBCMF$PQZ
⾣ .VUBCMFͳΒɺඇ6OJRVF࣌ͷΈNVUBCMF$PQZ
public mutating func append(_ other: Data) {
// ここで mutableCopy の必要性を判断・実施
_applyUnmanagedMutation { $0.append(other) }
}


# Page. 29

![Page Image](https://bcdn.docswell.com/page/87DY6GX87G.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍॻ͖ࠐΈେલఏͷੜ੒
⾣ ಺෦σʔλΛɺଈ࠲ʹ.VUBCMFͰੜ੒͢Δ͜ͱ΋
⾣ ॳճॻࠐ࣌ͷNVUBCMF$PQZΛ࡟‫ݮ‬
public init(capacity: Int) {
if let d = NSMutableData(capacity: capacity) {
_wrapped = _SwiftNSData(mutableObject: d)
} else {
}
}
fatalError(&quot;Unable to allocate data
of the requested capacity&quot;)


# Page. 30

![Page Image](https://bcdn.docswell.com/page/VJP6Y3PWE8.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍࢀর‫΁ܕ‬ͷม‫׵‬
⾣ 4XJGU/4%BUBͰอ࣋ͨ͠ࢀরΛ‫੍ڧ‬Ωϟετ
⾣ ‫ڍͳີݫ‬ಈ͸௫Ίͣʜߴ଎ಈ࡞ʹ͸‫ظ‬଴
public func _bridgeToObjectiveC() -&gt; NSData {
// NSData.self は 8 Byte
return unsafeBitCast(_wrapped, to: NSData.self)
}


# Page. 31

![Page Image](https://bcdn.docswell.com/page/2EV3G4297Q.jpg)

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍࢀর‫͔ܕ‬Βͷม‫׵‬
⾣ ࢀর‫͔ܕ‬Βͷม‫׵‬͸ɺ஋‫ܕ‬ͷΠχγϟϥΠβʔͰ
⾣ /4.VUBCMF%BUBʹඋ͑DPQZΛऔಘͯ͠#PYJOH
public static func _forceBridgeFromObjectiveC(
_ input: NSData, result: inout Data?) {
result = Data(referencing: input)
}
public init(referencing reference: NSData) {
_wrapped = _SwiftNSData(immutableObject:
reference.copy() as AnyObject)
}


# Page. 32

![Page Image](https://bcdn.docswell.com/page/57G381R4JL.jpg)

4NBMM7BMVF5ZQFT


# Page. 33

![Page Image](https://bcdn.docswell.com/page/4EQ59DVRJP.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
$PQZ*NNFEJBUFMZ
⾣ ߏ଄ମͷσʔλͱͯ࣋ͪ͠ɺϒϦοδ࣌ʹଈෳ੡
⾣ ͦͷ‫ޙ‬΋ɺผม਺΁୅ೖ͢ΔͨͼʹσʔλΛෳ੡
஋
8SJUF
Ϋϥε
σʔλ
#SJEHF
$PQZ
࣮ମ
σʔλ


# Page. 34

![Page Image](https://bcdn.docswell.com/page/KJ49XZMQ71.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
ଈ࣌ίϐʔͷಛ௃
⾣ ίϐʔͷ‫ݪ‬ଇʹ஧࣮
⾣ ୅ೖ΍ϒϦοδͰɺσʔλ෼ͷෳ੡ίετ͕ൃੜ
⾣ ࢀরΧ΢ϯτपΓͷ؅ཧίετͷ࡟আ


# Page. 35

![Page Image](https://bcdn.docswell.com/page/LE1KNR8LJG.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
4NBMM7BMVF5ZQFT

&quot;⒏OF5SBOTGPSN

%BUF

/PUJpDBUJPO


# Page. 36

![Page Image](https://bcdn.docswell.com/page/GEWD41ZQJ2.jpg)

%BUFͷ࣮ࡍ


# Page. 37

![Page Image](https://bcdn.docswell.com/page/47ZG2P13E3.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍ
⾣ /4%BUF΁ͷϒϦοδΛ૝ఆ
⾣ /4%BUF΁ͷࢀর͸࣋ͨͣɺσʔλΛ௚઀อ࣋
public struct Date
: ReferenceConvertible {
// NSDate とのブリッジ
public typealias ReferenceType = NSDate
// データを TimeInterval (Double) で直接保持
fileprivate var _time : TimeInterval


# Page. 38

![Page Image](https://bcdn.docswell.com/page/YJ6YVMLZ7V.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍΠϯελϯεԽ
⾣ ಺෦σʔλΛɺσʔλͱͯ͠௚઀࣋ͭ
⾣ /4%BUF͸ؔ༩͠ͳ͍
public init(timeIntervalSinceReferenceDate
ti: TimeInterval) {
_time = ti
}


# Page. 39

![Page Image](https://bcdn.docswell.com/page/GJ5GDZ19J4.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍฤू
⾣ ಺෦σʔλΛॻ͖‫͑׵‬Δ
⾣ ࣗ෼ઐ༻ͷσʔλͳͷͰɺࢀরͳͲ͸ߟྀෆཁ
public mutating func addTimeInterval(
_ timeInterval: TimeInterval) {
self += timeInterval
}


# Page. 40

![Page Image](https://bcdn.docswell.com/page/LE3RM91275.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍࢀর‫΁ܕ‬ͷϒϦοδ
⾣ ಺෦σʔλ͔Β/4%BUBΛੜ੒
⾣ ૉ௚͔ͭ࠷୹‫Ͱ཭ڑ‬ͷϒϦοδ
public func _bridgeToObjectiveC() -&gt; NSDate {
return NSDate(timeIntervalSinceReferenceDate:
_time)
}


# Page. 41

![Page Image](https://bcdn.docswell.com/page/8EDY6GX6EG.jpg)

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍࢀর‫͔ܕ‬ΒͷϒϦοδ
⾣ /4%BUBͷ౰֘৘ใ͔ΒΠϯελϯεΛੜ੒
⾣ ࢀর؅ཧ͔ΒಠཱʢࢀরΧ΢ϯτΛ‫ڞ‬༗͠ͳ͍ʣ
public
static func _conditionallyBridgeFromObjectiveC(
_ x: NSDate, result: inout Date?) -&gt; Bool {
result = Date(timeIntervalSinceReferenceDate:
x.timeIntervalSinceReferenceDate)
return true
}


# Page. 42

![Page Image](https://bcdn.docswell.com/page/V7P6Y3KZJ8.jpg)

஋‫Ͱܕ‬΋ɺ
ύϑΥʔϚϯεΛ‫ͨ͠ʹؾ‬ઃ‫ܭ‬


# Page. 43

![Page Image](https://bcdn.docswell.com/page/2JV3G4VMEQ.jpg)

/FX7BMVF5ZQFT
҆৺ͯ͠࢖ͬͯɺେৎ෉ͦ͏ɻ


# Page. 44

![Page Image](https://bcdn.docswell.com/page/5EG381LX7L.jpg)

&amp;OKPZ4XJGU
5IBOLZPV
/41SFpY֎఻
$PQZ0O8SJUF
&amp;;/&amp;5‫۽‬୩༑޺
IUUQF[OFUKQ
⾣
/FX7BMVF5ZQFT
⾣
0QUJNJ[BUJPO
⾣
%BUBͷ࣮ࡍɺ%BUFͷ࣮ࡍ


