Swiftについて聞きたいこと #cswift 

[第３回 カジュアル Swift 勉強会 ＠ 青葉台 : ATND](https://atnd.org/events/71769)の発表資料

## 自己紹介

[haranicle](http://haranicle.net/)

## いろいろ質問させてください

* みんなで"わからないこと"を共有したい
* StackOverflowでやれ的な内容でごめんなさい
* 粒度はバラバラです

## 質問1. classに所属してないfuncは何者..?

```swift
class Hoge {

    // こいつはわかる
    func fuga() {
    }

    // こいつもわかる
    class func huga() {
    }
}

// 誰だおまえ
func piyo() {
}
```

* piyo()はどこからでも実行できる?
* だれが持っているメソッド?
* Objective-Cでも同様のことが実現できる？

## 質問2. 循環参照について

* サンプルコード: [haranicle/MemoryLeaks · GitHub](https://github.com/haranicle/MemoryLeaks)

### Blocks (Objective-C)

```objc
#import "ObjCObject.h"

@interface ObjCObject ()
@property (nonatomic) NSString* title;
@property (nonatomic, copy) void (^completion)();
@end

@implementation ObjCObject

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.title = @"Objc Object";
    }
    return self;
}

// リークしない
- (void)doSomethingAsync {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"%@", _title);
    });
}

// selfがリークする
- (void)doSomething {
    self.completion = ^void() {
        NSLog(@"%@", _title);
    };
    _completion(); 
    // self.completion = nil; // これがあるとちゃんとreleaseされていることになる
}

// リークしない
- (void)doSomethingWithWeakSelf {
    __weak ObjCObject *weakSelf = self;
    self.completion = ^void() {
        NSLog(@"%@", weakSelf.title);
    };
    _completion();
}

@end

```

* なんでもweakSelfにしなくてもいいよね?
  * なんでもweakSelfにしちゃうと、weakSelfが意図しないタイミングでnilになっちゃうことがありえるから
* 主にpropertyでblocks持ってる時にのみ、blocks内からselfにアクセスしたらメモリリークするという認識で合ってる？
* warning出してくれるのは素敵
<img width="445" src="https://qiita-image-store.s3.amazonaws.com/0/8093/ab21d279-9952-8fda-b147-d8d5b6123947.png">
* ```self.completion = nil;```ってすると、メモリリークしてないっぽい
  * そもそもリリースカウント無視してnilぶっこめばメモリリークしない？
  * [前記事の補足:プロパティへのnil代入がreleaseの代わりになる理由 - iPhoneアプリ開発まっしぐら★ - iPhoneアプリ開発グループ](http://iphone-dev.g.hatena.ne.jp/tokorom/20100315/1268677134)
  * deallocはnilを代入することと等価なの???
  * SwiftだとOptional以外のプロパティは必殺nil代入releaseできないよね?
    * 代替手段ある？(そもそも必殺nil代入releaseするべきでない?)
    
* 参考
  * [Always pass weak reference of self into block in ARC?](http://stackoverflow.com/questions/20030873/always-pass-weak-reference-of-self-into-block-in-arc/20032131#20032131)
  * [Objective-CのBlocksの循環参照に関する僕なりのベストプラクティス](http://www.slideshare.net/katty0324/objectivecblocks "Objective-CのBlocksの循環参照に関する僕なりのベストプラクティス")

### Closure (Swift)

```swift
import UIKit

class SwiftObject: NSObject {
    var title = "Swift Object"
    var completion:(()->())?
    
    override init() {
        super.init()
    }
    
    // リークしない
    func doSomethingAsync() {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
            print(self.title)
        }
    }
    
    // selfがリークする
    func doSomething() {
        completion = { () in
            print(self.title)
        }
        completion?()
        // completion = nil // これがあるとちゃんとreleaseされていることになる
    }
    
    // リークしない
    func doSomethingWithWeakSelf() {
        weak var weakSelf = self
        completion = {() in
            print(weakSelf!.title)
        }
        completion?()
    }
    
    // リークしない
    func doSomethingWithCaptureList() {
        completion = {[weak self] () in
            print(self!.title)
        }
        completion?()
    }

}
```

* Swiftだとwarning出してくれない?
* Capture Listは、とりあえず```[weak self]```って書いておけばいいと思ってる
  * unowndの使いドコロとは
  * [help - Swiftのクロージャにおける循環参照問題でunownedとweakの使い分けがわからない - Qiita](http://qiita.com/susieyy/items/39efd4d34cf4c1f9d3ef#comment-67f67b836d80af0e7615)
     * オブジェクト破棄時にnilクリアされる??

## 質問3. Swifを気持よく書くための情報ください

* コードフォーマッタと静的解析を自動でしてほしい
  * コードフォーマッタと静的解析のルールがセットで用意されていてほしい
     * 例えば折り返し文字数とかは、それぞれのルールで統一されてないとだめなので
  * ルールはプロジェクトに紐づく形でチーム内で共有されていてほしい

### コードフォーマッタ

#### clang-format

* [swift support? · Issue #55 · travisjeffery/ClangFormat-Xcode · GitHub](https://github.com/travisjeffery/ClangFormat-Xcode/issues/55)
  * Clangの対応待ち

#### uncrustify

* [Swift support · Issue #351 · bengardner/uncrustify · GitHub](https://github.com/bengardner/uncrustify/issues/351)
  * なにも進んでない??

#### SwiftFormat

* [haaakon/SwiftFormat · GitHub](https://github.com/haaakon/SwiftFormat)
* Pythonで書かれたスクリプト
* Run Scriptとかに設定すれば、ビルド時に静的解析できそう
* 整形ルールとかはスクリプトちょくでいじらないといけなさそう
  * ちょっとつらい

#### Swift-Cleaner
* [niebloomj/Swift-Cleaner · GitHub](https://github.com/niebloomj/Swift-Cleaner)
* Pythonで書かれたスクリプト
* SwiftFormatと同じ感じ

#### 他にいいのない...?

### 静的解析

#### SwiftLint

* 公式: [realm/SwiftLint · GitHub](https://github.com/realm/SwiftLint)
* 日本語解説記事: [iOS - SwiftLintを試してみた - Qiita](http://qiita.com/ushisantoasobu/items/b494c9cf7d78a968b373)
  * homebrew or 自分でビルド で導入
  * [github/swift-style-guide](https://github.com/github/swift-style-guide)ベースのルール
  * .swiftlint.ymlというファイルにルール設定を記述できる
  * コード内で ```// swiftlint:disable <rule>```って書いたところから```swiftlint:enable <rule>```って書いたところまでルール無視できる
  * 良さそう

#### 他にいいのない...?

## 質問4. コーディング規約どうしてる?

* [raywenderlich/swift-style-guide](https://github.com/raywenderlich/swift-style-guide)
* [github/swift-style-guide](https://github.com/github/swift-style-guide)
* [iPhone - Swiftコーディング規約@Wantedly - Qiita](http://qiita.com/susieyy/items/f71435cc962e70d81b37)