Swift part10 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
さて、また荒らしと文字列の扱いについて談笑しようじゃないか 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秒待つ Dispatch Group使ってwaitするか DispatchWorkItem使ってwaitするか かな NSConditionでの実装例 ttp://swift.sandbox.bluemix.net/#/repl/58aab29626c3ba5cbe1d44ee 文字列でなんやかんや話してたエロい人たちがより良い例を出してくれると信じてる >>5 Sleep()がカッコ悪いのでsyncで呼ぶ let task = URLSession.shared.dataTask(with: url) { data, response, error in 動きがなんかおかしいと思ったら これcompletionHandler設定できてないような 最後に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() 関係ないけどこの外部ステートへの依存の仕方はちょっと気持ち悪く感じる var dic: Any = ["": ""] >>9 メソッド引数の最後のclosureは()から出して記述できるんでは? ただ、 DispatchQueue.main.async(execute: { print("dic = ¥(dic)") }) の部分がPlaygroundでは実行されるのに、terminal.appでは実行されない? >>10 素晴らしい! dispatchMain() このグローバル関数が何をしてるのか?ようわからんけど。 >>12 あらまほんとだ ラベル関係なく使えるのね Executes blocks submitted to the main queue. って事は、 DispatchQueue.main.async(execute: { print("dic = ¥(dic)") }) を実行しているみたいだ。dispatchMain()は。 exit(EXIT_SUCCESS)が無いと、dispatchMain()は永遠に実行待ちするみたい。 しょうが無いので、^Z + kill %1した。 while task.state == .running { RunLoop.current.run(mode: .commonModes, before: .distantFuture) } 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置くのと考えると問題を先送りしてるだけな気がする >>4 そうそう プログラミング言語史上類を見ない最強にエレガントでモダンな至高言語Swiftのスレだよ Enjoy! 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のサンプルはよ、一番これが「モダン」だと思う >>19 次の3つのGlobal関数内では使ってはイケナイって書いてある。 今回はOK! UIApplicationMain(_:_:_:_:) (iOS), NSApplicationMain(_:_:) (macOS), or CFRunLoopRun() >>20 追伸です。 19のコメントは間違ってました。 アプリ内で使うのは良く無いそうです。Terminal.Appで実行する時だけにした方が良いです。 >>20 その顔文字みたいなのは何なの?... 間違いじゃないなら可読性絶望的すぎじゃね? >>22 セレクタでっせ。 メソッド名とラベルから構成される。ラベルが省略されたセレクタもあって、underscoreで省略可を示す訳だ。 C++で言う、シグネチャだわな。 セレクタを記述できないと、Notificationを扱う事ができないので、mustな! Overload resolver(メソッド多重定義解決)はセレクタ情報を手掛かりに、どのメソッドを呼び出すのか?解決する訳だ。 参照:C++ FAQ Objective-Cのときってもっとわかりやすい表記だったような ObjCの表記を覚えてない => ObjC使ってない Swiftの表記を自然に読み取れない => Swift使ってない うーん、このどうしようもない感 swiftってiosアプリ書く以外であえて選んでるって人いるの? >>19 current threadのrunloopインスタンスのmethodを呼び出しているのだからまったく問題ないだろ… 1日経って思ったけど、 >>17 じゃtaskを待ってはいるけど completionHandlerを待ってはいないから >>5 への回答には全くなってなかったね 忘れてくれ completionHandlerに入った時点でtask.stateは.completedだった >>33 他に適したAPIがある上、while state がsleep 並にダサい 無限ループで状態監視とか日曜プログラマでも回避するコードだ 特に無限ループがダサいとは思わないけどな 少し低いレイヤーを意識したコードではあると思うけど 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); } スクリプトモードでメインスレッドでメインキューを待つ方法と、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") >>36 ttp://swift.sandbox.bluemix.net/#/repl/58ac0f8c861c326c636916bf 一般常識として無限ループの状態監視するやつは死ねと思う SIGNALが使えないほどの低レイヤーでそれが必要だとしてもsleepは入れる ループ中にsleep入れないなら死ぬし、sleep入れるなら本末転倒だよねー ビジーループと無限ループをごっちゃにして死ねとかアホか RunLoopのSwift実装読んだけど酷過ぎじゃね returnAfterSourceHandledを強制trueにして ブロッキングキューの利点ぶち壊すとか意味分からん 別実装で書いてみた http://swift.sandbox.bluemix.net/#/repl/58ac26055d046936d91eba1c CFRunLoopRunInMode(,,false)がポンコツでなければ キューが空の間はセマフォのwait等と同様に 待機状態になるはずでCPUは消費しない PR出してみたら?コードがあるなら前スレのAffineTransformよりはマシなレビューが期待できそう 出すとしたら https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSRunLoop.swift#L149 > CFRunLoopRunInMode(modeArg, ti, true) ここの第3引数も指定出来て, CFRunLoopRunInModeの戻り値をenumに入れ替えて返す runのオーバーロード追加を要求するくらいか とはいえコンソール系でのテスト実行以外では UIApplicationMain等に任せる所だし放置になるのでは >>5 質問と直接関係ないけど この文脈でのsleep()はc言語の、つまりPOSIX APIのsleep()が呼び出されると思うんだよな 無自覚にインラインCになっちゃうって、便利なのか?、危険なのか? >>48 Thread Type Method sleep(forTimeInterval:) こんなのもあるね。秒単位ね。 import class Foundation.Thread RxSwiftのソース眺めてたら、見たことの無いimport文発見。 これに関してどっかに記述あるかなぁ? import class文を使えばコンパイル時間を短縮できたり、バイナリサイズを小さくできるのかな? import Foundation // 42500 byte import Foundation.NSData // 42484 byte import class Foundation.NSData // 42500 byte let data = NSData() swiftc -O でビルド、なんで減るんだよwww ABI安定(予定)の4で変わるだろうし、あんま意味ないな 名前空間の汚染だけじゃないの でも種別を明記するのは定義側がうっかり変更されたときにすぐ気づくためかな Evolution/README読む限りだとSwift 4 Stage 1に入ってるぞ?MLでも特に上がってないよな 今更リスケしても気にしないけども それはそれとして、Stage 2が切られてStage1/2にソース互換性ないよってのに笑った もうSwift5としてリリースすればいいじゃんよ... >>51 >import class GRAMMAR OF AN IMPORT DECLARATION import import kind module.symbol name import module.submodule ちゃんと書いてあるのね >>57 俺は職場からカキコしてる。 今はもちろん、自宅で寝る前だけど。 生みの親が辞めた言語にしがみついてる人達のスレはここですか? カキコって何年ぶりに見ただろうか おっちゃん、ちょっと感慨深いぜ >>62 自動制御を追求しにいった彼が 後に再登場してSwiftをDriftに進化させる王道展開を待つわ 今はなんていうんだ? 送信ボタンを押してるとか言えばいいのか? rustライクなメモリ管理は本気だったのか https://github.com/apple/swift-evolution/blob/master/README.md まだ正式なプロポーサル上がってないけど、Stage1でABIレベルで仕様入れて、Stage2で文法決定なんかね >>65 Ryzenのように? でも、彼も自動運転に行っちゃったよ shared_ptrを文法糖衣したARC同様に、unique_ptrを文法糖衣したナニカになる予感 それだけならアポーでも出来るだろうし、ObjCへのバックポートも可能だからアリだろ >>70 Ted KremenekさんがRelease Managerやってるよ。Swift4の。 至高の言語Swiftはどこまでアップデートが続くのかな 至高中の至高に達するのはいつ? すでに至高の域には達してるだろ 今は最後のピストン運動が激しくなって絶頂に向かってるところだ 1年後?のSwift 4 Stage 2で言語仕様の破壊変更加えて 2年後のSwift5でコード下位互換を保証して 4年後のSwift6でコード下位互換をしつつ、文法のブラッシュアップしてようやく至高に至る そこまでswiftコミュニティが死んでなければだけど、AppleとIBMは諦めろと思う 荒らしに来てる子たちはまだまだ遊べるよ、やったね 至高ってどっち向けに至高かで全然違うとは思うが、、、 FortranもCも進化をやめる気が無いのを見ると いつまでも変化し続けるんだろうね、言語って COBOLは知らん c++はもはや俺には理解できない領域まで到達してるが さらに進化を加速しようとしている 変化速度で至高を目指しているのか? >>76 クリストスだけで先に逝っちゃったに空目した WWDC2017まであと3ヶ月ちょっとにまで迫って来た。 Swift3.1ももうそろそろXcode8.3と共に出荷かな! Swift 4 Stage 1 すらWWDCには間に合いそうにないな 言語仕様の破壊はもう気にしてないから、betaやってた頃みたいに半年周期でリリースしてくれよなぁ 至高と究極と最強と最高と極限と元祖と本家で戦うんですね 自ら限界を定めてしまったらそこで発展は終わってしまうからな 直感的な文法と安全性を兼ね備えたパーフェクト言語のスレはここですか クラスの配列のディープコピーのやり方を教えてちょんまげ。 助けて太い人っ! 敬虔にググりたまへ さすれば汝に福音が齎されるであろう アーメン ここで文字列の扱いを議論してた荒らしがrustスレに行って暇になったなぁ 文法の固定されたrustより、文法があと5年は変わり続けることが約束されたswiftの方が面白いのに... 三項演算子とか{}ブロックとか、基礎的な文法はswiftならまだまだ変わりうるぜ? >>89 そんなんじゃ誰も釣れないだろ、、、 もっと頑張れ var a = 0 var b = 0 var array = [a, b] a = 1 array[0] ←これを1にしたい array[1] = 10 b ←これを10にしたい どうすればいい? そんなことできる言語はないと思うけど なんでそんなことしたいの? 複数の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が出る なんだ、ポインター使いたいのか UnsafeMutablePointer とかググると使いかた出てくるよ こんな感じで 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) 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が出る ああ、>>99 だと、ほぼそのまま置き換えできますね。ありがとうございます。 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 にするか、作りながら判断します。ありがとうございました。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる