Swift

Swift/C&Objective-Cとのデータの受け渡し

データ型の互換性

C言語の単純型とSwiftの型

C言語の単純型Swiftの型
char, signed charInt8, CChar
unsigned charUInt8, CUnsignedChar
shortInt16, CShort
unsigned shortUInt16, CUnsignedInt
intInt32, CInt
unsigned intUInt, CUnsignedInt
longInt, CLong
unsigned longUInt, CUnsignedLong
long longInt64, CLongLong
unsigned long longUInt64, CUnsignedLongLong
wchar_tUnicodeScalar, CWideChar
char16_tUInt16, CChar16
char32_tUnicodeScalar, CChar32
floatFloat, CFloat
doubleDouble, CDouble

C援護の関数 pow, sqrt の例(Foundationのモジュールのimportが必要)

func powf(_: Float, _: Float) -> Float
func pow(_: Double, _: Double) -> Double

func sqrtf(_: Float) -> Float
func sqrt(_: Double) -> Double

C言語のポインタとSwiftの型

APIを経由してひとまとまりのデータの受け渡しを行う場合は、 Swiftで配列を用意しておき、その配列への「ポインタ」をCの関数に渡して 値を読み書きしてもらう方法が一般的。

ポインタには nil を代入でき、演算子 ==, != を用いてポインタとnilと比較することもできる。

種類C言語の型Swiftの型
ポインタconst T*UnsafePointer<T>
T*UnsafeMutablePointer<T>
void*UnsafeMutablePointer<Void>
クラスTのインスタンスconst T*UnsafePointer<T>
_strong T*UnsafeMutablePointer<T>
T**AutoreleasingUnsafeMutablePointer<T>
関数T (*func)(U)@convention(c)(U)->T
T (*func)(void)@convention(c)() -> T
ブロックT (^block)(U)@convention(block)(U)->T
空ポインタnil/NULL(任意のポインタ型)nil

型の名称に Unsafe がついているのはメモリ管理を ARC で行っていないことを表している。 これらを Unsafe Pointer と呼ぶことにする。

Mutable は、ポインタが指すメモリ領域に書き込んで変更できることを表す。

変数を用意して関数の結果を書き込む

func time(_: UnsafeMutablePointer<time_t>) -> time_t
func localtime_r(_: UnsafePointer<time_t>,_:UnsafeMutablePointer<tm>) -> UnsafeMutablePointer<tm>
import Darwin
var current = time(nil)   // current は time_t 型になる

ポインタには「変数のポインタを渡す」場合と「配列の先頭要素を渡す」場合がある。 変数のポインタを渡す場合は、実引数として "&" をつけた変数を記述する(inout 演算子がついた引数に渡す場合と同様)。

var current: time_t = time_t()    // 変数を用意して初期化
time(&current)                    // 変数 current に値が書き込まれる
import Darwin   // Foundation でもよい
var current : time_t = time(nil)   // 現在時刻を time_t 型で取得
var tnow = tm()                    // 変数を用意して初期化
localtime_r(&current, &tnow)       // 変数 tnow に情報が書き込まれる
print("\(tnow.tm_mon + 1)月\(tnow.tm_mday)日")  // 本日の日付が表示される

配列を用意して関数の結果を書き込む

time_t型データから、日時を表す文字列を生成する ctime_r 関数を使ってみる。 第1引数は time_t型へのポインタで、第2引数が文字列領域へのポインタである。 C 言語の char 型は Swift では Int8 型なので 文字列領域へのポインタは UnsafeMutablePointer<Int8> となる。

func ctime_r(_: UnsafePointer<time_t>, _: UnsafeMutablePoiner<Int8>) -> UnsafeMutablePointer<Int8>

配列のポインタを関数に渡す場合、使い方は次の2通り。

  • 渡した配列の内容を関数で変更する場合。配列名に "&" を付けて渡す。
  • 渡した配列の内容を関数で変更しない場合。配列名に "&" を付ける必要はない。
import Darwin
var buf = (Int8)(count: 26, repeatedValue: 0)   // 26個の0
var current: time_t = time(nil)
ctime_r(&current,&buf)                          // 文字列がbufに得られる
puts(buff)                          // 現在時刻が表示される
// puts(&buff)    // &をつけても同じ結果が得られる

変数bufの値は Swift の String 型ではないので、表示するのに print 関数は使えない。 C言語の puts を使うことはできる。 putsではポインタの内容を変更しないので、putsに与える実引数には & をつけても つけなくてもどちらでも同じ動作となる。

var tt = [time(nil) ]    // time_t 型の配列を作り、第1要素を初期化する
ctime_r(tt,&buf)         // &tt でも動作する

ポインタへの値の渡し方

UnsafePointer<T> ~ 読み取り専用UnsafeMutablePointer<T> ~ 読み書き可能
値が1つの変数 x:T&x&x
配列 a:[T]aまたは&a&a

C言語ポインタ引数に関するルール

Swift でC言語の fopen関数を使ってファイルをオープンするコード

let fpin = fopen(path,"r")   // 引数はSwiftの String 型

関数 fopen の Swift インタフェース

func fopen(_: UnsafePointer<Int8>, _: UnsafePointer<Int8>) -> UnsafeMutablePointer<FILE>

String型と UnsafePointer<Int8> 型は互換ではない。 C言語のAPIを用いてSwiftを動作させるために、ポインタ引数については特別ルールがある。

  1. 関数の引数が UnsafePointer<T> 型で定義されているとき、次の型の実引数を受け取ることができる。
    • nil
    • UnsafePointer<T>
    • UnsafeMutablePointer<T>
    • AutoreleasingUnsafeMutablePointer<T>
    • T型の引数に & を付けたもの (inoutが指定された引数と同様)
    • T型の値。配列の先頭として渡され、配列は呼び出しが終わるまで保持される。 &はつけてもつけなくても動作する。配列リテラルで渡すこともできる。
    • String。ただし、Tは Int8 か UInt8 の場合。 文字列はバッファ内で UTF-8 に変換され、バッファは呼び出しが終わるまで保持される。
  2. 配列の引数が UnsafePointer<Void> 型で定義されているとき、任意の型 T の ポインタ UnsafePointer<T> について、上記1.で受取可能とした実引数を指定できる。
  3. 関数の引数が UnsafeMutablePointer<T> 型で定義されているとき、 次の型の実引数を受け取ることができる。
    • nil
    • UnsafeMutablePointer<T>
    • T型の書き込みが可能な変数に & をつけたもの。
    • [T]型の書き込みが可能な変数に & をつけたもの。
  4. 関数の引数が UnsafeMutablePointer<Void> 型で定義されているとき、 任意の型 T のポインタ UnsafeMutablePointer<T> について、上記3.で 受取可能とした実引数を指定できる。

このルールにより Swift の String 型を C 言語の文字列のように渡すことができているが、 逆はできない。

引数として UnsafePointer<T> を受け取るC言語の関数に UnsafeMutablePointer<T> を渡しても動作する。しかし、 Swift では UnsafeMutablePointer<T> と UnsafePointer<T> は異なる型なので、 型の変換を明示する必要がある。

let p: UnsafeMutablePointer<Int8> =  /* 何かの値 */
let q: UnsafePointer<Int8>(p)        // ポインタの型を変換する
let z: UnsafePointer<Int8> = p       // エラー。Swiftではこの代入はできない。

unsafe pointer 間での相互変換は自由にできる。 つまり、T型とU型が無関係であっても UnsafePointer<T> を UnsafePointer<U> に、 UnsafeMutablePointer<T> を UnsafeMutablePointer<U> に変換できる。どちらの型も2つのイニシャライザを持っている。

init<U>(_ from: UnsafeMutablePointer<U>)
init<U>(_ from: UnsafePointer<U>)

型パラメータ U には何の制限もないので、次のような変換も可能である。

let p: UnsafePointer<Int8> = /* char 型を読み出し可能な何らかのポインタ */
let q = UnsafeMutablePointer<Int32>(p) = /* 整数値を書き込み可能なポインタ */

渡されたポインタから値 を取り出す

リエントラント(再入可能)でスレッドセーフな関数は名前の末尾に _r がついている。 元々 Unixで用意されていた関数は localtime, ctime でありリエントラントではない。 これらを Swift から利用してみる。

func localtime(_: UnsafePointer<time_t>) -> UnsafeMutablePointer<tm>
func ctime(_ UnsafePointer<time_t>) -> UnsafeMutablePointer<Int8>

3種類の unsafe pointer は Swift では構造体として定義されており、 ポインタの指す内容にアクセスするプロパティ memory と、 参照しているメモリを先頭から配列のように参照できる添字付けの機能を提供している。

// UnsafeMutablePointer<T> 型の場合
var memory: T { get nonmutating set }
subscript (i: Int) -> T { get nonmutating set }

UnsafeMutablePointer<T> は C 言語の (T*) 型に相当する。 これらの型をもつ変数 p の値にアクセスするには、C言語では *p と、 Swift では p.memory と記述する。 ポインタの位置からデータ n 個分先のデータにアクセスするには C言語でもSwiftでも p[n] と記述する。

// unsafe pointer に直接アクセスする例
import Darwin
var current = time(nil)
let jnow: tm = localtime(&current).memory   // 構造体をコピーして代入する
print("\(jnow.tm_mon + 1)月\(jnow.tm_mday)日")
let p = ctime(&current)      // pは UnsafeMutablePointer<Int8>型

for i in 0..<25 {            // 添字を使って文字にアクセスする例
  putchar(Int32(p[i]))       // putcharの引数はint型(Int32型)
}                            // 最後の文字は改行文字

var ptr = p                  // ポインタを進めながら文字にアクセスする例
for i in 0..<25 {
  putchar(Int32(ptr.memory)) // ポインタの指すデータを表示する
  ptr = ptr.successor()      // ポインタを1つ進める
}

Swift ではポインタを直接変数に代入することはできないので、定数jnow には tm 型の構造体の コピーが代入される。

ポインタから文字列への変換

String型のタイプメソッドを使う。

static func fromCString(_: UnsafePointer<CChar>) -> String?
let p = ctime(&current)      // pはUnsafeMutablePointer<Int8>型
if let s = String.fromCString(p) {  // オプショナル束縛構文
  print(s)
}

Foundation を import している場合、String型に対して次のイニシャライザが利用可能である。 文字列が UTF-8 でなかった場合は nil が返される。

init?(UTFString: UnsafePointer<CChar>)

コマンドラインの引数にアクセスする。

コマンド引数にアクセスするために、列挙型 Process が定義されていて、 タイププロパティを使って引数リストにアクセスできる。

static let arguments: [String]
static var argc: CInt { get }
static var unsafeArgv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>> { get }
var i = 0
for elm in Process.arguments {
  print("\(i++): \(elm)")
}

UnsafeBufferPointer<T>を利用する

unsafe pointer には添字でアクセスする方法以外に、 プロトコル CollectionType に適合している 構造体 UnsafeBufferPointer<T> を利用する方法もある。

uptr: UnsafePointer<Int> = /* 略 */
let array = UnsafeBufferPointer<Int>(start: uptr, count: 100) // 先頭から100個分のInt型

T**型の引数の扱い

  • TがC言語の単純型の場合
    C言語の T** は Swift では UnsafeMutablePointer<UnsafeMutablePointer<T>> となる。
  • TがObjective-Cのクラスの場合
    Objective-Cでは、メソッドに渡される T** 型は 「クラス T のインスタンスを格納するローカル変数へのポインタ」 または「nil」であり、グローバル変数や配列であってはならない。 Swift側からObjective-C側にポインタを渡すとき(ローカル変数でなくても構わないが) T**型を AutoreleasingUnsafeMutablePointer<T> として扱う。すなわち、渡されたポインタがnilでなければ、クラスTのインスタンスが 一時的に作成されて利用され、関数の終了時にポインタが指す先にコピーされる。

対応付けられたデータ型

数値と数値オブジェクト

Objective-C の NSInteger と NSUInteger はどちらも Swift の Int 型に対応付けられる。

Objective-C のインタフェースで NSNumber のインスタンスが使われる部分には Swift の Int, UInt, Float, Double, Bool 型のインスタンスがに 対応付けられる。

var n: NSNumber = 10.25
print(n as Float)    // 10.25 が表示される
print(n as Int)      // 10 が表示される

オブジェクト

Swift には AnyObject? 型があり、任意のクラスのインスタンスに対応付けられる。

Foundation を import してあれば、Objective-C のクラスに対応付けられた型は 全て Swift の AnyObject? に対応付けることが可能である。

C++ のオブジェクトは Swift では利用できない。

文字列

Swift のString 型と Objective-C のNSString型は 対応付けられている。

String型には NSString のメソッドを適用できるが、逆はできない。

var s: String = "protects the knowledge of the strong"
print(s.rangeOfString("owl")!)   // 15..<18 が表示される。
s = "クロネコ\u{1F431}"           // 顔文字を含む
print((s as NSString).length)    // 6 が表示される
var m = NSMutableString(string: "小鳥\u{1F426}")
s = m as String
// var mm = s as NSMutableString   // エラー。このキャストは不加能。

NSString型は UTF16 を用いて Unicode を扱っているため、 顔文字などが含まれる文字列の長さを1つずつ多く間違えてしまうという問題がある。 NSStringのほとんどの機能は Foundation を import すれば String 型から使えるので NSString型に変換して機能を利用する必要はない。

Swift の String 型と Objective-C の NSMutableString 型は対応付けられていないので、 互いに自由に変換はできない。 ただし、NSMutableString型は NSString型のサブクラスなので、String型に変換することはできない。

NSString はクラスクラスタなので、実際の型が NSString であるとは限らない。

配列と集合

Swift の Array 型と Objective-C の NSArray 型は対応付けられており、 NSArray 型で型パラメータを指定しない配列オブジェクトは Swift の [ AnyObject ] という型に対応付けられる。

let ns1: NSArray = [ 152.0, 4, UInt(1) ]
let ar1 = ns1                            // [ AnyObject ] 型になる
let ar2 = ns1 as! [Int]                  // [ Int ] 型にできる
print(ar2)               // [ 152 4 1 ] が表示される
let dat:[Int] = [ 161, 152, 160, 153 ]
let ns2: NSArray = dat       // NSNumber* の配列になる

as! で型変換した場合、キャストできない要素があると実行時エラーになる。 as? で型変換した場合は、キャストできない要素があると nil が返される。

Objective-C から渡された [ AnyObject ]型の配列の要素がそれぞれ異なる型の場合、 たとえば文字列だけを取り出したい場合は次のようにクロージャを利用する。

var array: [ AnyObject?] = /* NSArray型 */

let strs = array.filter{ $0 is String }

集合型では、 Swift の Set 型と Objective-C の NSSet 型が対応付けられている。 Swiftの Set 型の要素はプロトコル Hashable に適合している必要がある。

辞書

Swift の Dictionary 型と、Objective-C の NSDictionary は対応付けられている。 型パラメータを指定しない場合 Swift の [ NSObject : AnyObject ] という型となる。

let info: NSDictionary = [ "Height" : 161.0, "Grade" : 2, "Level" : 5 ]
let pinfo = info as! [String:Int]   // このキャストは可能。
print(pinfo)   // [ "Height": 161, "Grade" : 2, "Level" : 5 ] が表示される

一般に Objective-C から渡される辞書には複数の型が含まれているので、 ダウンキャストには as? 演算子を用いるか、要素毎に個別に対応した方がよい。

for (key, value) in info {
  if let k = key as? String, v = value as? Int {  // [String:Int]な要素だけを扱う
    print(k + ": ", v)
  }
}

または

for enry in info {
  if case let (k as String, v as Int) = entry {  // (String, Int)だけを扱う
    print(k + ": ", v)
  }
}

NSValue と CoreGraphics? の構造体

CFLoat型はDoubleの場合とFloatの場合があるので、 Objective-Cでは自動型変換で大丈夫であっても、 Swiftではエラーとなることがある。 イニシャライザを使って明示的に型変換を行うとよい。

var xp: CFLoat = CGFloat(sin(th))    // sin() の返り値はDouble
var x2: Double = Double(xp * xp)

CoreGraphics で定義されている構造体

データ型Foundationの名称プロパティ
点の座標CGPointNSPointvar x:CGFLoat
var y:CGFloat
縦横の大きさCGSizeNSSizevar width:CGFloat
var height: CGFloat
長方形領域CGrectNSRectvar origin:CGPoint
var size:CGSize

Swiftでは Objective-C で使われている CGPoint, CGSize, CGRect 構造体をそのまま 利用できる。

NSData

Objective-C の NSData に対応づけられた Swift の型はないので、 [Int8] 型、または [UInt8] 型でバイト列のデータをやりとりする。

Objective-C から受け取ったNSDataからデータを読み出すには、プロパティ bytes か、 メソッド getBytes を使うとよい。

var bytes: UnsafePointer<Void> { get }
func getBytes(_: UnsafeMutablePointer<Void>, length: Int)

Swift で NSData のインスタンスを作ることができる。2番目のイニシャライザはデータをコピーせず共有する。

init(bytes: UnsafePointer<Void>, length: Int)
init(bytesNoCopy: UnsafePointer<Void>, length: Int)

データのバイト数を調べる

Swift では、型名を指定してバイト数を得る sizeof() 関数、 変数や値を指定してそのバイト数を得る sizeofValue() 関数。

sizeof(Int)            // 8 (64bitマシンの場合)
sizeof((Int8,Int8))    // 2
sizeofValue(3.14)      // 8

パディングを考慮した値を得るには strideof() と strideofValue() 関数を使う。

strideof(Float80)                  // 16
strideofValue(["Cinderella":346])  // 8

Core Foundation

Foundation を import すると Core Foundation も import されている。 Core Foundation のオブジェクトを表す型名は CFArrayRef , CFURLRef のように 参照型であることを示す Ref がついているが、Swiftでは 「Ref のある型名」も「Refのない型名」も両方使える。 Core Foundation の CFTypeRef? 型は Swift の AnyObject? 型として扱われる。

Core Foundation の型には toll-free (型変換なしにObjective-Cで相互利用できる) なものがあるが、これは Swift でも利用できる。

Core FoundationObjective-C (Foundation)
CFArrayRefNSArray
CFMutableArrayRefNSMutableArray
CFDataAefNSData
CFMutableDataAefNSMutableData
CFDateAefNSDate
CFDicitonaryAefNSDictionary
CFMutableDictionaryAefNSMutableDictionary
CFStringAefNSString
CFMutableStringAefNSMutableString
CFNumberAefNSNumber
CFURLAefNSURL

列挙型とその他のデータ

列挙型

C言語やObjective-Cにおける列挙型は整数型とあまり明確な区別はなかったが、 次のどの形式で定義されたかによって Swift からの見え方が異なる。

  • 型名のある列挙型
  • 型名のない列挙型
  • NS_ENUM マクロで定義された列挙型
  • NS_OPTIONS マクロで定義された列挙型

型名のある列挙型

enum AIMAbility {
  AIMAccelerator = 1,
  AIMDarkMatter,
  AIMElectromaster
};

Swift向けのインタフェースは次のような構造体として定義される。 プロトコル RawRepresentable? はこの型が実体を持つことを表わし、 プロパティ rawValue が各要素の値を返す。

public struct AIMAbility : RawRepresentable, Equatable {
  public init(_ rawValue: UInt32)
  public init(rawValue: UInt32)
  public var rawValue: UInt32
}
public var AIMAccelerator : AIMAbility { get }
public var AIMDarkMatter : AIMAbility { get }
public var AIMElectromaster : AIMAbility { get }

型名のない列挙型

enum { Male, Female }

この場合、Swiftの宣言ではメンバ名自体が Int 型の定数になり、構造体は構成されない。

public var Male: Int { get }
public var Female: Int { get }

マクロ NS_ENUM で定義された列挙型

マクロ NS_OPTIONS で定義された列挙型

マクロ定義

CやObjective-Cで定義された定数値を表す単純なマクロは、 Swift ではグローバルな定数として表現される。

#define WLRegulation  1.048596    // Objective-Cのマクロ定義
let WLRegulation = 1.048596       // Swift のグローバルな定数

引数を持つ関数マクロは、Swiftには情報として取り込まれることはない。

共用体とビットフィールド

Swift では、通常の方法ではC言語の共用体のようなデータ構造は定義できないが、 そのようなデータにアクセスしたり、新しいインスタンスを生成したりすることは可能である。

typedef union IntChars {    // C言語における共用体の定義
  int i;
  unsigned char c[4];
} IntChars;
public struct IntChars {    // 上記の共用体に対応する Swift のインタフェース
  public var i: Int32
  public var c: (UInt8, Uint8, Uint8, Uint8)
  public init(i: Int32)
  public init(c: (UInt8, Uint8, Uint8, Uint8))
  public init()
}

ビットフィールドについても同様である。

struct WNumber {     // C言語におけるビットフィールド
  unsigned int flag:1    // 1 bitのみのフィールド
  unsigned int pad:7,    // 7 bitのみのフィールド
  IntChars data;         // 共用体
}
public struct WNumber {  // 上記のビットフィールドに対応するSwiftのインタフェース
  public var flag: UInt32
  public var pad: UInt32
  public var data: IntChars
  public init()
  public init(flag: UInt32, pad: UInt32, data: IntChars)
}

各国語対応の文字列を得る

Foundationの関数NSLocalizedString?()を利用する。

func NSLocalizedString(key: String,
    tableName: String? = default,   // 省略時は Localizable.strings
       bundle: NSBundle = default,  // 省略時は メインバンドル
	 value: String = default,    // 省略時は nil
      comment: String) -> String

let mesg = func NSLocalizedString("Welcome", comment:"起動メッセージ")

日本語リソースの Localizable.strings に "Welcome" = "ようこそ" という 登録があれば、日本語を取り出せる。

関数ポインタ

Objective-C の関数へのポインタは、Swiftでは

@convention(c) T

として扱う。Tは関数を表す型で、たとえば「()->Int32」。

@convention(c) 属性によって、 「この関数がC言語の関数へのポインタであり、 Swiftのクロージャのように環境から値をキャプチャすることはない」 ことを示している。

C言語のAPIに関数ポインタとして渡すことができるのは、

  • Swiftのトップレベルの関数
  • クロージャのリテラル
  • nil のどれかである。 この条件を満せば、SwiftのクロージャとCの関数へのポインタは同じものとして扱うことができる。
void qsort(void *base, size_t nel, size_t width, int(*compar)(const void *, const void *));
typealias Episode = (String, Int)
var buf:[Episode] = [ ("Parade",10), ("Baltazar", 5), (Pacusi", 1) ]
qsort(&buf,buf.count,strideof(Episode)){
  (x:UnsafePointer<Void>, y:UnsafePointer<Void>) -> Int32 in
  let s: Episode = UnsafePointer<Episode>(x).memory
  let r: Episode = UnsafePointer<Episode>(y).memory
  return Int32(s.1 - r.1)
})
print(buf)  // [ (Pacusi", 1),  ("Baltazar", 5), ("Parade",10) ] が表示される

C言語のブロックオブジェクト

Objective-C で定義されたブロックオブジェクトを Swift に渡して処理を行わせることができる。

Tはブロックオブジェクトの引数と返り値を表す型であり、たとえば「() -> Int32」。

@convention(block) T
int scale = 15;
[calc setScaleBlock:^(int n) {
  return n * scale;
}];

このブロックオブジェクトは、swiftでは次のような型の変数に格納できる。 外側の括弧がないと型の解釈があいまいになることに注意(typealias宣言を使って別の名前をつけるとよい)。

var block: (@convention(block) (Int32) -> Int32) !

変数 block は Swift のクロージャであるかのように、引数を渡して実行が可能。 実行時には渡されるときにキャプチャした値(scale = 15)が使われる。

Null許容性 (nullability)

Swiftのオプショナル型は変数がインスタンスを参照する場合としない場合(nil)を区別して扱うためのものであるが、 Objective-Cではあまり区別していなかった。 このようなObjective-Cの特性を扱うために導入された概念が Null 許容性 (nullability) である。

  • NULL (または nil) でもよい場合 -- Null許容 (nullable)
  • NULL (または nil) ではいけない場合 -- Null非許容 (nonnulable)

Objective-C の Null 許容性の表現

  • _Nullable --- Null許容。値が NULL や nil の場合がある。
  • _Nonnull --- Null非許容。値が NULL や nil の場合はない。
  • _Null_unspecified --- 指定なし。値が NULL や nil の場合がある。

クラス UIImage のクラスメソッド + imageWithData?: は引数に関しては Null非許容であり、返り値は Null許容である。

+ (UIImage * _Nullable) imageWithData: (NSData * _Nonnull) data;

型修飾子ではなく、キーワード nullable, nonnull, null_resettable(初期値にだけNULLやnilを許容する) も使うことができる。

+ (nullable UIImage *) imageWithData: (nonnull NSData *) data;

オプショナル型と Null 許容性の関係

Objective-CSwift
nonnull非オプショナル型 (T)
nullableオプショナル型 (T?)
指定なし有値オプショナル型 (T!)
null_resettable~
_Null_unspecified~
//Objective-C
@interface HestiaParty: Party
@property (retain, nonnull) NSString *hero;
@property (retain, nullable) NSString *helper;
@property (retain, null_resettable) NSString *knife;
@property (weak) NSString *supporter;
+ (nonnull instancetype) familia: (nullable NSString *) famous;
+ (nullable instancetype) initWithhero: (nonnull NSString *) hero;
@end
// Swift
public class HestiaParty : Party {
  public var hero: String
  public var helper: String?
  public var knife: String!
  public var supporter: String?   // weakだと、インスタンスが開放されたときゼロ化される(nilになる)ので
  public class func familia(famouse: String?) -> Self
  public init?(hero: String)
}

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-06-09 (木) 13:20:35 (1456d)