質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

1359閲覧

なぜクロージャの外でAddSubViewするコードが多いのか?

hodoru3sei

総合スコア284

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/09/24 08:43

クロージャを使ってそのなかでViewの詳細を定義する書き方を見かけます。
下記の例ではTaskButtonに一度格納してクロージャの外でaddSubViewしていますが、クロージャの中で全てをやってしまいたいと考えました。

Swift

1let TaskButton:UIButton = { 2 let button = UIButton() 3 button.layer.masksToBounds = true 4 button.layer.cornerRadius = 50.0 5 button.frame = CGRect(x:0,y:0,width:self.view.frame.width/4,height:self.view.frame.width/4) 6 button.backgroundColor = .red 7 button.layer.position = CGPoint(x: self.view.frame.midX, y: self.view.frame.height - self.view.frame.midY) 8 button.setTitle("追加", for: UIControlState.normal) 9 button.addTarget(self, action: 10 #selector(addTask), for: .touchUpInside) 11 return button 12 }() 13 self.view.addSubview(TaskButton)

クロージャの中で全てやってしまうコード

Swift

1var _ = { ()->() in 2 let button = UIButton() 3 button.frame = CGRect(x:0,y:0,width:self.view.frame.width/4,height:self.view.frame.width/4) 4 button.backgroundColor = .red 5 button.layer.position = CGPoint(x: self.view.frame.midX, y: self.view.frame.midY) 6 button.setTitle("ボタン", for: UIControl.State.normal) 7 self.view.addSubview(button) 8 }()

クロージャの中でaddSubViewまでやってしまうコードをネットでみたことがありません、何が問題があるのでしょうか?
個人的にはクロージャの中でaddSubViewまでやったほうが綺麗な気がしたのに例を見つけられなかったので疑問に思いました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

参考程度ですが、私は中に書いてしまう事が多いです。
昔のiOSではViewControllerのviewは非表示かつメモリ不足時に破棄されるという仕様だったため、
viewに紐付いているコントロールもメンバで保持する場合はweakにすべきという風習がありました。

そのためその頃の名残で今でも

swift:

1private weak var hogeButton: UIButton? 2 3override loadView() { 4 super.loadView() 5 6 hogeButton = { 7 let b = UIButton() 8 .... 9 view.addSubview(b) 10 return b 11 }() 12}

などと書く癖が残っています。
弱参照なので、一度viewに追加して参照カウンタを増やしてからでないと代入できないためです。

今、この時代にわざわざこの方法(弱参照で保持)を採る必要はありませんので、あくまでご参考まで。

※ちなみに中でも外でも言うほどの差は無いと思います。

投稿2018/09/25 07:12

編集2018/09/25 07:22
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

基本UIはCustomView以外Storyboardでほとんど済ませるので個人的な見解になりますが、

上記の例ではUIButtonの生成とそのプロパティの割り当てだけと割り切っています。ですが、下記の例のようにself.view.addSubview(button) まで入れてしまうとTaskButtonは自身だけでなくviewまで抱え込んでしまうことになります。どちらがより疎であるか、という点を考えた場合、下記の例よりも上記の例の方がより疎であるといえるでしょう。なので```self.view.addSubview(button)

投稿2018/09/24 09:01

xAxis

総合スコア1349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hodoru3sei

2018/09/24 11:52

TaskBottonもButtonというViewの一種なのだと思っていました。 MVCをまだ理解できていないのですが、もしかしてTaskButtonをControllerクラスで生成してaddSubViewはViewクラスで実装するみたいに分けることができなくなってしまうので上記の例の方が良いってことなのでしょうか
xAxis

2018/09/24 12:53

UIViewのの一種、と言うよりはTaskButtonはUIButtonで宣言されてますし、クロージャ内でUIButtonを返していますのでUIButtonそのものですね。 うーん、addSubViewは多分UIViewControllerでやるものだと思うのでちょっと違う気がしますが、 > 分けることができなくなってしまう この部分は正しいですし、考え方のベクトルもあってると思います。もしかしたら感覚的な理解かもしれませんが大事な部分です。 MVCもそうですしModel同士、View同士、Controller同士でも疎結合であればあるほど良いとされています。疎結合というのは簡単に言えば二者間の関連性が薄いことです。疎結合であれば片方に変更があった場合もう片方に対する影響が少なくてすみます。逆に密結合である場合、片方に変更があった場合もう片方にも大きな変更を余儀なくされることがあります。 なので > 分けることができなくなってしまう ようなコードは避けた方が、プロジェクトメンバーにとっても優しいのはもちろん、自分自身にとってもメリットが大きいですよ。 あとコメントしていて気づいたのですが下記の例だと変数名がないのでremoveFromSuperViewが出来ないですね。
fuzzball

2018/09/25 00:36

>>TaskBottonもButtonというViewの一種なのだと思っていました。 xAxisさんの言っているviewはself.viewのことじゃないですかね。 で、addSubViewはself.viewがやることなので、TaskButtonの処理に含めるべきではないと思います。(どうでもいいですが、変数名はtaskButtonの方がいいと思います) 下のコードってクロージャにする意味あるの?って思ってしまいますが‥。 ちなみに私は(今のところ)クロージャは使わない派です。(関数化します)
xAxis

2018/09/25 00:52

>> fuzzballさん いつも補足ありがとうございます。 > xAxisさんの言っているviewはself.viewのこと はおっしゃる通りです。言葉足らずでした。 > ちなみに私は(今のところ)クロージャは使わない派です。(関数化します) 自分もUIに関してはCustomClassで関数化しちゃいます。他の場面でもほとんど関数化しちゃいますね。クロージャを使う場面といったら関数内で使う事があるくらいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問