X



Swift part10 [無断転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん 転載ダメ©2ch.net (ワッチョイ 3b3c-eq+O)
垢版 |
2017/02/20(月) 10:00:13.40ID:ChbPWtRt0
WWDC2014で発表されたAppleの新言語Swiftについて語りましょう

関連スレ

プログラミング言語Swift Part4
http://potato.2ch.net/test/read.cgi/mac/1484763495/

[SDK]iPhoneアプリ開発初心者質問箱48[touch][iPad]
http://potato.2ch.net/test/read.cgi/mac/1484217623/

Xcode part14
http://potato.2ch.net/test/read.cgi/mac/1476190499/

Swiftアンチスレ part1
http://echo.2ch.net/test/read.cgi/tech/1458491343/

前スレ
Swift part9
http://echo.2ch.net/test/read.cgi/tech/1476758084/
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
0002デフォルトの名無しさん (ワッチョイ 7ba1-vagz)
垢版 |
2017/02/20(月) 11:06:31.94ID:Gb72M66o0
< `∀´>ニダー
0005デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/20(月) 16:05:25.21ID:IDSTiL890
WebAPIを叩く最小限のコードを書いています。
Terminal.Appで実行したところ、動くには動くのですが、最後のsleep文をコメントアウトすると、結果が表示されません。
sleep文はダサいので、うまい具合にbackgroundで実行中のThreadを待ち合わせる方法は無いでしょうか?なお、Swift3.0.2です。

import Foundation
var dic: Any = ["": ""]

func printJSON(_ data: Data) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
dic = json
print(json)
} catch {
print("parse error!")
}

}
let url = URL(string: "http://date.jsontest.com/";)!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let jsonData = data {
printJSON(jsonData)
DispatchQueue.main.async(execute: { print("dic = ¥(dic)") })
//mainスレッドを捕まえて実行
}
}
task.resume()
print("OK")
sleep(1) // 1秒待つ
0010デフォルトの名無しさん (ワッチョイ 5f3c-Scgb)
垢版 |
2017/02/20(月) 21:45:53.42ID:E/pOlJmJ0
最後にdispatchMain()を追加して明示的にexit()すればいいみたい
http://stackoverflow.com/questions/31944011/how-to-prevent-a-command-line-tool-from-exiting-before-asynchronous-operation-co

#! /usr/bin/env swift
import Foundation

var dic: Any = ["": ""]

func printJSON(_ data: Data) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
dic = json
print(json)
} catch {
print("parse error!")
}

}

let url = URL(string: "http://date.jsontest.com/";)!
let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
if let jsonData = data {
printJSON(jsonData)
DispatchQueue.main.async(execute: {print("dic = ¥(dic)"); exit(EXIT_SUCCESS)})
}
})

task.resume()
print("OK")
dispatchMain()
0012デフォルトの名無しさん (ワッチョイ 8b5b-fFgi)
垢版 |
2017/02/20(月) 21:53:42.29ID:4Xv+kGUd0
>>9
メソッド引数の最後のclosureは()から出して記述できるんでは?
ただ、
DispatchQueue.main.async(execute: { print("dic = ¥(dic)") })

の部分がPlaygroundでは実行されるのに、terminal.appでは実行されない?
0013デフォルトの名無しさん (ワッチョイ 8b5b-fFgi)
垢版 |
2017/02/20(月) 22:01:34.57ID:4Xv+kGUd0
>>10
素晴らしい!
dispatchMain()
このグローバル関数が何をしてるのか?ようわからんけど。
0015デフォルトの名無しさん (ワッチョイ 8b5b-fFgi)
垢版 |
2017/02/20(月) 22:12:48.75ID:4Xv+kGUd0
Executes blocks submitted to the main queue.

って事は、
DispatchQueue.main.async(execute: { print("dic = ¥(dic)") })
を実行しているみたいだ。dispatchMain()は。
exit(EXIT_SUCCESS)が無いと、dispatchMain()は永遠に実行待ちするみたい。

しょうが無いので、^Z + kill %1した。
0017デフォルトの名無しさん (ワッチョイ 5fc9-fFgi)
垢版 |
2017/02/20(月) 23:26:54.19ID:SiY39E3I0
extension URLSessionTask {
func wait() {
while state == .running {
RunLoop.current.run(mode: .commonModes, before: .distantFuture)
}
}
}

let task = ...dataTask(...) { ... }
task.resume()
task.wait()

これならdownloadTaskとか他のtaskでも、上のextensionで1つで全部対応できていいと思う
task.wait()だけで済むから、DispatchGroupとかDispatchSemaphoreみたいにenter/leave/signalとかが各所に散らばる面倒臭さもない

DispatchSemaphore使ってsyncDataTaskみたいなのextensionに書く例stackoverflowにあったけど
これでもいいけど他のtask使いたくなったとき、そのtaskのsyncバージョンをまた別に書かないといけないのが面倒臭い
http://stackoverflow.com/a/34308158

dispatchMainはexitの置き場所で困りそう
2つのtask待ち合わせるならどこにexit置くのと考えると問題を先送りしてるだけな気がする
0019デフォルトの名無しさん (ワッチョイ bbbd-ea4t)
垢版 |
2017/02/21(火) 07:58:47.31ID:eTJT09tJ0
dispatchMain
> Applications ... must not call dispatchMain()

RunLoop
> You should never try to call the methods of an RunLoop object running in a different thread

なんでリファレンスで危ないから使うなって言われてるものを優先して挙げるのか
DispatchWorkItemのサンプルはよ、一番これが「モダン」だと思う
0020デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/21(火) 08:14:40.71ID:3Vda5W860
>>19
次の3つのGlobal関数内では使ってはイケナイって書いてある。
今回はOK!

UIApplicationMain(_:_:_:_:) (iOS), NSApplicationMain(_:_:) (macOS), or CFRunLoopRun()
0021デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/21(火) 08:17:33.97ID:3Vda5W860
>>20
追伸です。
19のコメントは間違ってました。
アプリ内で使うのは良く無いそうです。Terminal.Appで実行する時だけにした方が良いです。
0024デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/21(火) 08:47:28.88ID:3Vda5W860
>>22
セレクタでっせ。
メソッド名とラベルから構成される。ラベルが省略されたセレクタもあって、underscoreで省略可を示す訳だ。
C++で言う、シグネチャだわな。
0025デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/21(火) 08:49:53.12ID:3Vda5W860
セレクタを記述できないと、Notificationを扱う事ができないので、mustな!
0026デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/21(火) 08:53:52.12ID:3Vda5W860
Overload resolver(メソッド多重定義解決)はセレクタ情報を手掛かりに、どのメソッドを呼び出すのか?解決する訳だ。
参照:C++ FAQ
0034デフォルトの名無しさん (ワッチョイ 5fc9-fFgi)
垢版 |
2017/02/21(火) 16:29:44.15ID:m+/zu2/z0
1日経って思ったけど、 >>17 じゃtaskを待ってはいるけど
completionHandlerを待ってはいないから >>5 への回答には全くなってなかったね
忘れてくれ
completionHandlerに入った時点でtask.stateは.completedだった
0037デフォルトの名無しさん (ワッチョイ 5f3c-Scgb)
垢版 |
2017/02/21(火) 18:08:20.55ID:aFqTV30T0
DispatchWorkItem版
if #availableはguard文だとコンパイル通らなかった‥

if #available(OSX 10.10, *) {
let queue = DispatchQueue(label: "queue", attributes: .concurrent)
let printTask = DispatchWorkItem { print("dic = ¥(dic)") }
let url = URL(string: "http://date.jsontest.com/";)!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let jsonData = data {
printJSON(jsonData)
queue.async(execute: printTask)
}
}

task.resume()
printTask.wait()
exit(EXIT_SUCCESS)

} else {
print("require OSX10.10 or newer"); exit(EXIT_FAILURE);
}
0038デフォルトの名無しさん (ワッチョイ 5fc9-fFgi)
垢版 |
2017/02/21(火) 18:37:29.74ID:m+/zu2/z0
スクリプトモードでメインスレッドでメインキューを待つ方法と、URLSessionで同期的に実行する方法で問題をごっちゃにしてたな
>>5 の質問の本意がどっちにあるのかわからないけど、「スクリプトモードでメインスレッドでメインキューを待つ方法」ならRunLoopを回すのが正しい回答なはず


単純化すれば
DispatchQueue.main.async {
sleep(1)
print("Hello")
}
print("Done")
これでスクリプトモードでどうやって "Hello" を表示させるか
できれば"Hello"→"Done"の順序で

この場合DispatchSemaphore等ではwaitした時点でメインキューに入れた非同期タスクに永久にたどり着けないのでwaitで固まるので誤り
待ってるのも非同期タスクも両方メインだから
let sema = DispatchSemaphore(value: 0)
DispatchQueue.main.async {
sleep(1)
print("Hello")
sema.signal()
}
sema.wait()
print("Done")
0039デフォルトの名無しさん (ササクッテロリ Sp9f-31xI)
垢版 |
2017/02/21(火) 19:10:04.95ID:IX256A9wp
>>36
ttp://swift.sandbox.bluemix.net/#/repl/58ac0f8c861c326c636916bf
一般常識として無限ループの状態監視するやつは死ねと思う
SIGNALが使えないほどの低レイヤーでそれが必要だとしてもsleepは入れる

ループ中にsleep入れないなら死ぬし、sleep入れるなら本末転倒だよねー
0045デフォルトの名無しさん (ワッチョイ 3b3c-eq+O)
垢版 |
2017/02/21(火) 21:58:36.49ID:5UhBXSO50
出すとしたら
https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSRunLoop.swift#L149
> CFRunLoopRunInMode(modeArg, ti, true)

ここの第3引数も指定出来て,
CFRunLoopRunInModeの戻り値をenumに入れ替えて返す
runのオーバーロード追加を要求するくらいか

とはいえコンソール系でのテスト実行以外では
UIApplicationMain等に任せる所だし放置になるのでは
0048デフォルトの名無しさん (スッップ Sd7f-yXFx)
垢版 |
2017/02/22(水) 12:33:22.98ID:pE0UWB3Fd
>>5
質問と直接関係ないけど

この文脈でのsleep()はc言語の、つまりPOSIX APIのsleep()が呼び出されると思うんだよな

無自覚にインラインCになっちゃうって、便利なのか?、危険なのか?
0049デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/22(水) 12:36:17.73ID:XTvCwCCI0
>>48
Thread Type Method sleep(forTimeInterval:)
こんなのもあるね。秒単位ね。
0050デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/22(水) 12:38:33.65ID:XTvCwCCI0
import class Foundation.Thread
RxSwiftのソース眺めてたら、見たことの無いimport文発見。

これに関してどっかに記述あるかなぁ?
0051デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/22(水) 12:40:01.01ID:XTvCwCCI0
import class文を使えばコンパイル時間を短縮できたり、バイナリサイズを小さくできるのかな?
0052デフォルトの名無しさん (ササクッテロリ Sp9f-31xI)
垢版 |
2017/02/22(水) 12:58:12.17ID:3150ESkMp
import Foundation // 42500 byte
import Foundation.NSData // 42484 byte
import class Foundation.NSData // 42500 byte
let data = NSData()

swiftc -O でビルド、なんで減るんだよwww
ABI安定(予定)の4で変わるだろうし、あんま意味ないな
0055デフォルトの名無しさん (ササクッテロリ Sp9f-31xI)
垢版 |
2017/02/22(水) 14:35:19.19ID:3150ESkMp
Evolution/README読む限りだとSwift 4 Stage 1に入ってるぞ?MLでも特に上がってないよな
今更リスケしても気にしないけども

それはそれとして、Stage 2が切られてStage1/2にソース互換性ないよってのに笑った
もうSwift5としてリリースすればいいじゃんよ...
0056デフォルトの名無しさん (ワッチョイ 8bc9-ykbm)
垢版 |
2017/02/22(水) 14:40:41.89ID:XTvCwCCI0
>>51
>import class
GRAMMAR OF AN IMPORT DECLARATION

import import kind module.symbol name
import module.submodule

ちゃんと書いてあるのね
0059デフォルトの名無しさん (ワッチョイ 8b5b-fFgi)
垢版 |
2017/02/22(水) 21:15:19.95ID:2Tf2dKVi0
>>57
俺は職場からカキコしてる。
今はもちろん、自宅で寝る前だけど。
0060デフォルトの名無しさん (スップ Sd7f-6x/Q)
垢版 |
2017/02/22(水) 21:23:54.82ID:SjZ14kj8d
>>59
カキコって何?
0067デフォルトの名無しさん (スプッッ Sd4a-N8zA)
垢版 |
2017/02/23(木) 08:18:54.84ID:ft7494bRd
初カキコ、ドモッ…

だっけ?
0068デフォルトの名無しさん (ワッチョイ 533c-JtgB)
垢版 |
2017/02/23(木) 08:23:03.50ID:KoyZyoDT0
今はなんていうんだ?
送信ボタンを押してるとか言えばいいのか?
0073デフォルトの名無しさん (ワッチョイ bfc9-LZzl)
垢版 |
2017/02/24(金) 09:25:16.26ID:/HtdY5ya0
>>70
Ted KremenekさんがRelease Managerやってるよ。Swift4の。
0077デフォルトの名無しさん (ササクッテロリ Sp23-Cmgt)
垢版 |
2017/02/25(土) 12:25:30.42ID:hUBRL+mAp
1年後?のSwift 4 Stage 2で言語仕様の破壊変更加えて
2年後のSwift5でコード下位互換を保証して
4年後のSwift6でコード下位互換をしつつ、文法のブラッシュアップしてようやく至高に至る

そこまでswiftコミュニティが死んでなければだけど、AppleとIBMは諦めろと思う
荒らしに来てる子たちはまだまだ遊べるよ、やったね
0078デフォルトの名無しさん (ワッチョイ 6a93-LqKA)
垢版 |
2017/02/25(土) 13:12:00.62ID:vyst4/NK0
至高ってどっち向けに至高かで全然違うとは思うが、、、

FortranもCも進化をやめる気が無いのを見ると
いつまでも変化し続けるんだろうね、言語って
COBOLは知らん


c++はもはや俺には理解できない領域まで到達してるが
さらに進化を加速しようとしている
変化速度で至高を目指しているのか?
0080デフォルトの名無しさん (ワッチョイ 7f5b-JtgB)
垢版 |
2017/02/26(日) 19:53:22.76ID:ywDEPWcp0
WWDC2017まであと3ヶ月ちょっとにまで迫って来た。
Swift3.1ももうそろそろXcode8.3と共に出荷かな!
0086デフォルトの名無しさん (スプッッ Sd4a-moPN)
垢版 |
2017/02/28(火) 12:39:25.27ID:rcWZYEudd
クラスの配列のディープコピーのやり方を教えてちょんまげ。

助けて太い人っ!
0088デフォルトの名無しさん (ワッチョイ bb7b-Cmgt)
垢版 |
2017/02/28(火) 14:31:53.07ID:ydx77xTP0
ここで文字列の扱いを議論してた荒らしがrustスレに行って暇になったなぁ
文法の固定されたrustより、文法があと5年は変わり続けることが約束されたswiftの方が面白いのに...
三項演算子とか{}ブロックとか、基礎的な文法はswiftならまだまだ変わりうるぜ?
0093デフォルトの名無しさん (アウアウオー Sabf-0QZk)
垢版 |
2017/03/05(日) 10:30:38.29ID:Nn8WRk/za
var a = 0
var b = 0
var array = [a, b]
a = 1
array[0] ←これを1にしたい
array[1] = 10
b ←これを10にしたい

どうすればいい?
0096デフォルトの名無しさん (アウアウオー Sabf-0QZk)
垢版 |
2017/03/05(日) 11:01:41.19ID:Nn8WRk/za
複数のIntやCGFloat(クラスではない型)を、個別でアクセスと、配列化してインデックスでアクセスを出来るようにして、状況に応じて切り替えたいのです。C言語ならポインタの配列にすればよいのですが、Swiftでどうやるのかなと思いまして。

int a = 0;
int b = 0;

int *arr[2];
arr[0] = &a;
arr[1] = &b;

a = 1;
printf("%d¥n", *arr[0]); ←1が出る

*arr[1] = 10;
printf("%d¥n", b); ←10が出る
0098デフォルトの名無しさん (アウアウエー Sabf-pTz+)
垢版 |
2017/03/05(日) 11:21:57.99ID:4SdvbjFEa
こんな感じで

typealias IntPointer = UnsafeMutablePointer<Int>

var a_ptr = IntPointer.allocate(capacity: 1)
var b_ptr = IntPointer.allocate(capacity: 1)
a_ptr.pointee = 0
b_ptr.pointee = 0

var array = [a_ptr, b_ptr]

a_ptr.pointee = 1
print(array[0].pointee) ←1が出る

array[1].pointee = 10
print(b_ptr.pointee) ← 10が出る

a_ptr.deallocate(capacity: 1)
b_ptr.deallocate(capacity: 1)
0099デフォルトの名無しさん (アウアウエー Sabf-pTz+)
垢版 |
2017/03/05(日) 11:28:57.98ID:4SdvbjFEa
Alloc/Dealloc 使わないバターン

typealias IntPointer = UnsafeMutablePointer<Int>

var a = 0
var b = 0
var a_ptr = IntPointer(&a)
var b_ptr = IntPointer(&b)

var array = [a_ptr, b_ptr]

a_ptr.pointee = 1
print(array[0].pointee) ←1が出る

array[1].pointee = 10
print(b_ptr.pointee) ←10が出る
0100デフォルトの名無しさん (アウアウオー Sabf-0QZk)
垢版 |
2017/03/05(日) 11:44:51.09ID:Nn8WRk/za
ああ、>>99だと、ほぼそのまま置き換えできますね。ありがとうございます。
0101デフォルトの名無しさん (アウアウオー Sabf-0QZk)
垢版 |
2017/03/05(日) 12:06:49.29ID:Nn8WRk/za
pointeeを隠蔽してこうなりました。

struct IntPointerStruct {
var a_ptr: IntPointer
var b_ptr: IntPointer

subscript(index: Int) -> Int {
get {
switch index {
case 0: return a_ptr.pointee
case 1: return b_ptr.pointee
default: return 0
}}
set {
switch index {
case 0: a_ptr.pointee = newValue
case 1: b_ptr.pointee = newValue
default: break
}}}}

var a = 0
var b = 0
var array = IntPointerStruct(a_ptr: &a, b_ptr: &b)
a = 1
print(array[0]) ←1が出ます!!
array[1] = 10
print(b) ←10が出ます!!

これにするか >>99にするか、作りながら判断します。ありがとうございました。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況