LoginSignup
25
26

More than 5 years have passed since last update.

[Swift] ちょこちょこハマったメモ

Last updated at Posted at 2014-06-18

ハマったことをちょこちょこメモしていきます。
なので随時update気味。


ProjectName-Swift.h.hで読み込もうとしてエラー

ファイルは生成されているのになんでだーと思っていたら、どうも.mファイルのほうで読み込まないとダメな模様。
知らないと謎いエラーでハマる。


NSStringFromClassから生成される文字

xibファイルの読み込みに、ファイル名を指定するときにそのクラス名を利用して読み込む、ということをやる場合があると思います。
その場合、Swiftにすると、NSStringFromClass(Hoge.self)のように指定することになりますが、これだとうまく行きません。

理由としては、これで生成される文字列はクラス名のみではなく、モジュール名も付加されたものになるからです。

var nibName: String = NSStringFromClass(Hoge.self) // => "ModuleName.Hoge"

配列を特定の個数で初期化

与えられた引数の数だけ配列の中身を初期化したい場合の処理。

array-init.swift
var a: Double[] = []

// ちなみにbeta3から以下のように書式が変わった模様
// var a: [Double] = []

// -----------

a = Array<Double>(count: num, repeatedValue: Double())

クラス([NSString class] etc)を渡す方法

クラス自身の参照を渡す必要があるときに、どうやるんだろうと思って調べたのでメモ。
答えはselfプロパティを利用する、でした。
詳細はStackOverflowで。

class-ref.swift
class TestClass {
    var name: String!
    @required init() {
        self.name = "name!"
    }
}

var t = TestClass.self

// 参照からインスタンスを生成する場合は、initに@requiredが必要
var t2 = t()
println(t2.name)

Objective-CでSwiftのクラスを利用する際の注意点

通常のSwiftクラスを使う場合は自動生成される<#ProductName#>-swift.hファイルをimportすればOK。
しかし、そのSwiftクラスがさらにObjective-Cのクラスを継承している場合は注意が必要。
上記の<#ProductName#>-swift.hをimportする前に、上記の継承元のクラスを宣言したヘッダファイルをimportしておかないとCannot find interfaceエラーが出て怒られる。
(冷静に考えれば当然だけど、ふと忘れそうなのでメモ)

Objective-CのenumをSwift側で使う

公式ドキュメントから引用すると、

enum-sample.m
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
};

こう定義されたものは、

enum-sample.swift
enum UITableViewCellStyle: Int {
    case Default
    case Value1
    case Value2
    case Subtitle
}

こう解釈されるらしい。
そのため、もしSwift側で利用する場合は、Objective-C側の名称ではないので注意。

enum-sample2.swift
var type = UITableViewCellStyle.Default

メソッド引数のラベルを無名にする「_」

インスタンス生成時、コンストラクタの引数のlabelは必須だが、定義時に_を使うとlabelがいらなくなる。

under-score.swift
class Hoge {
    var name: String?
    init(name: String) {
        self.name = name
    }
}

// 基本はlabel「name:」が必要。
var hoge: Hoge = Hoge(name: "namae")
under-score2.swift
class Hoge {
    var name: String?
    init(_ name: String) {
        self.name = name
    }
}

// initの宣言時に`_`をつけるとlabelを省略できるようになる。
var hoge: Hoge = Hoge("namae")

この辺りはObjective-Cのものとある程度互換性を持たせようとしたのでしょうか。
ただ、メソッド内部で宣言した関数に関してはlabelは必須ではないようです。
おそらく、内部関数は外部に公開されないから、と考えています。(あくまで推測)

non-label.swift
class Hoge {
    var name: String?
    init(name: String) {
        self.name = name
    }
    func doMethod() {
        func add(a: Double, b: Double) -> Double {
            return a + b
        }

        println("10.0 + 20.3 = \(add(10.0, 20.3))")
    }
}

ランダムな数字を作る

random.swift
// 1〜6を作る
var num = arc4random_uniform(UInt32(6)) + 1
25
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
26