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

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

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

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Swift

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

Q&A

5回答

4246閲覧

mvcのmodelについて教えて下さい

yoppy0066

総合スコア293

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Swift

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

0グッド

0クリップ

投稿2015/08/01 11:49

編集2015/08/01 17:45

swiftでiosアプリ開発の勉強中で、mvcのmodelについて調べているのですがちょっとわからなくなったので教えて下さい

まず、modelはシングルトンで実装する。ものなのでしょうか?

作りたいのは以下のようなものだとします
・メモの一覧画面(ListViewController)
・メモの詳細画面(DetailViewController)
※一覧画面の情報は外部のapiから取得するものとします

で、やりたかったこととしては詳細画面でデータの変更などを行った場合に一覧画面でも反映させるといったことで、シングルトンなmodelを作って以下のような実装になるのかなと考えました

で、疑問に思ったのがモデルをシングルトンにするとたとえば一覧にはいくつもカテゴリなどがあったとするといきなり破綻する気がしました、、、
こういう場合はモデルにそれぞれのカテゴリごとのlistを持つような実装にするのが一般的なのでしょうか?

モデル
`
ModelMemo: NSObject {
var list: [Dictionary<String,AnyObject>]

func getByApi() { // apiからデータを取得してlistにセット } func update() { // apiからデータを更新してlistに反映 }

}
`

一覧画面
`
class ListViewController: UIViewController {
var memos: ModelMemos

override func viewDidLoad() { self.memos = ModelMemos・・・->getInstance() self.memos->getByApi() }

}
`

詳細画面
`
class DetailViewController: UIViewController {
var memos: ModelMemos

override func viewDidLoad() { self.memos = ModelMemos・・・->getInstance() var memo = self.memos->getByRow(行番号とか) } func updateMemo() { self.memos.update() }

}
`

mvcとかあんまりわかってないので全然ちがってたらすみませんが、どなたかご教授いただけないでしょうか

__moaiさんへ

実装したい機能のイメージとしては以下のようなものになります

  1. セグメントコントロールに新着・人気がある
  2. セグメントコントロールの下にリストがある(テーブルビューで実装)
  3. リストの各セルにはブックマークボタンがあり、登録中・解除中で色が変わる
  4. リストのセルをタップすると詳細画面へ遷移する
  5. 詳細画面にもブックマークボタンがある

で、悩み出した原因としては詳細ページでブックマークして一覧に戻ったときにブックマークの状態をリストにも反映させなくてはいけないなというところから始まりました。
また、セグメントコントロールを切り替えた際にも同様の問題が起きえます

そして今検討中のコードが以下のようなものになります

`
class ModelDemo : NSObject {
// 新着リスト・人気リスト
dynamic var list: [Dictionary<String,AnyObject>] = Dictionary<String,AnyObject>
dynamic var list2: [Dictionary<String,AnyObject>] = Dictionary<String,AnyObject>

class var sharedInstance : ModelNotes { ・・・ } // APIの処理など

}

// 一覧ページ
class ListViewController : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

// リストデータの監視 ModelDemo.sharedInstance.addObserver(self, forKeyPath: "list", options: .New, context: nil) // apiでのデータ取得 ModelDemo.sharedInstance.getList() } // データの監視 override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { tableView.reloadData() } // ブックマーククリック func onclickBookmark(sender: UIButton) { // apiをたたいて更新 ModelDemo.sharedInstance.update(・・・) // 画面更新のためにこちらも更新 ModelDemo.sharedInstance.list[sender.tag]["isBookmark"] = true }

}

// 詳細画面
class DetailViewController: UIViewController {
// 選択された行番号
var row: Int!

// ブックマーククリック func onclickBookmark(sender: UIButton) { // apiをたたいて更新 ModelDemo.sharedInstance.update(・・・) // 画面更新のためにこちらも更新 ModelDemo.sharedInstance.list[row] = true }

}
`

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

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

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

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

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

guest

回答5

0

ここで行っているModelは、
ブックマークの内容と、ブックマークの状態をまとめたクラス、ということですよね?

モデルデータを配列や辞書に格納してそこからデータを引き出すのであれば、
前回の質問の回答にあった、シングルトンで実装するのが一番自然でしょう。

モデルのデータ表現が複雑になるのであれば、そのデータ単体を表現するModelクラスを作成するのがよいかと。

モデルクラスには、現在のブックマークの内容と状態をget/setするメソッドを実装しておき、
ViewControllerのアクションでブックマークの状態が変化したらModelクラスのsetで状態を更新させる、
ViewControllerのビューが更新されるタイミングでModelクラスにブックマークの内容と状態を問い合わせる、
というのがただしいかと。

swift

1 2class ModelDemo : NSObject { 3 4 // モデルを一意に識別できるような変数が必要。APIアクセスでリストにIDがついているならそれを入れる 5 var api_id: Int 6 var demoName: String 7 var content: String 8 var isNew: Bool 9 var isPopular: Bool 10 var bookmarked: Bool 11 12 init(name:String, content:String, new: Bool, popular: Bool) { 13 // 初期化コードは省略 14 } 15 // 以下、プロパティの更新メソッド等々 16}

みたいなモデル一つ一つを表現するModelクラスを作成して、
そのModelを更新したり、新着などのフラグでリスト取得するような処理は、
モデル(って言っていいのかな?ヘルパー?)クラスを別途作るか、モデルクラスのクラスメソッドで対応し、
ViewControllerはそこからリストを取得するようにすると良いかと。

swift苦手なので、コードはあくまで雰囲気で。

投稿2015/08/01 22:50

rifuch

総合スコア1901

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

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

0

ごめんなさい、前回の回答で混乱させてしまいましたかね・・
MVCっていうのはプログラムの設計でいう概念的なお話なので、特に拘って悩むようなことでもないですよ

まず簡単に概念を実例を交えて説明をすると

View

アプリの表示している画面を作ってる部分、iOSだとUIViewがそうですね

Controller

ユーザーからの操作を受け取ってModelに伝える部分、UIViewControllerがそうですね

Model

ここで出てくるのがModelなんですが、基本的にViewでもControllerでもないコードを指します


例えば電卓アプリを作っていたとして、電卓のボタンだったり背景だったりをViewとするなら、ユーザーがボタンを押して画面に数字を出させるためのイベントを起こすのがController、電卓の+を押したときに計算される足し算のロジックとかの部分はModel

なので画面とは関係無いようなView/Controller以外のコードをModelと思って問題ないかなーと思います(なのでapiと通信する部分もModelですね)

そしてここからはModelって広い括りの中のお話になるのですけど、シングルトンっていうのは一旦忘れて、データをどうやって画面と画面の間で使い回すかってことを考えていきましょう

yoppy0066さんが扱いたいのはどんなデータですか?

投稿2015/08/01 16:27

__moai

総合スコア264

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

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

yoppy0066

2015/08/01 17:47

丁寧にご回答いただきありがとうございます。 私の理解が足りなくてmvcとかとはまた別の話になってきている気もしてきました、、、 内容が長くなったため質問欄に追記させていただきました
guest

0

回答者の方の意見が異なるように、MVCは結構意見が異なることが多いように思います。
その証拠に、MVC以外にもMVVMあったりMVPだったり、色々な考え方があります。

なので、MVCはなにを達成するためのものなのか、を自分なりに考えて答えを出すのがいいのだろうと最近では思うようになりました。

ちなみにこのスライドが一番しっくり来てなるほど、と思ったので共有しておきます。
http://www.slideshare.net/mokemokechicken/iosandroidmodel

そして上記のスライドを元に考えてみると、Cocoa Framework内でもCoreDataがスライドで語られているものに近いかな、と思います。

Modelは基本死なず、質問者さんが言うようにシングルトンで作ってもいいと思います。
そしてMVCでViewとくっつくのはモデルではなく、エンティティですね。CoreDataで言うと。

つまりモデルはいわゆるデータベースそのものに近く、内部のデータをエンティティとして扱います。
そしてそれらのデータをどう使うか、という部分をコンテキスト(NSManagedContext)が担う、という構成です。

今回の質問に当てはめてみると、データを保持しておくのがモデル。
一覧や詳細で使われる生のデータがエンティティ。
そして編集されたりして、データの更新などを管理するのがコンテキストでしょうか。

これ以降はどう設計するかと、どういうコンセプトで作るかによるので一概にこれがこうです、とはならないと思います。

あと質問内に「カテゴリ」と書かれていますが、ちょっとこれがなにを指すかが分かりませんでした。
データはあくまでデータでしかないので、それをカテゴライズしてどう表示するかは「データをどう扱いたいか」を自身で定義し、それを実装することになると思います。
(例えばデータにカテゴリの枠を設けて、カテゴリ単位で抽出し、それをリストとして表示する、とか)

上でも書いたようにデータはあくまでデータでしかなく、カテゴライズするのはコントローラだったり、の部分が担うことになると思います。

と、長々と書きましたが最初にも書いたように、表示とデータを分離しておくといいよね、というのがMVCの発端であり、それをどう理解して実装するかは実装者それぞれの判断になるかと思います。

とはいえどうすりゃいいんだ、ってのも分かるので、まずはCoreDataの実装を参考にしてみるのもいいかもしれません。

投稿2015/08/01 16:18

edo_m18

総合スコア2283

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

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

0

何でモデルはシングルトンであるという考えに至ったのか謎ですが、
モデルは別にシングルトンである必要はありません。

MVCという言葉はいろんな人が色んな意味で使ってますが、
基本、MV○系のModelと言うのは、単に「UI実装の詳細を知らない部分」ぐらいの広い範囲です。
例えばメモなら
メモクラスや
メモをどこかに永続化するクラスとか
メモの生成・読み込み・更新・削除手順を提供するクラスとか
外部APIのラッパークラスとか
これら全部「Model」です

投稿2015/08/01 12:15

ozwk

総合スコア13521

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

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

yoppy0066

2015/08/01 12:35

ご回答頂きありがとうございます。 いまいちイメージがつかないのですが、今回の例だとどのようなコードになるのが一般的なのでしょうか?
guest

0

MVCのModelはオブジェクトじゃなくて、コンポーネントです。
だから、シングルトン・オブジェクトという考え方はありません。
また、1クラス=1コンポーネントという対応もありません。

今回、カテゴリというものが必要なら、カテゴリを持つModelコンポーネントを作るだけです。

投稿2015/08/01 12:09

Stripe

総合スコア2183

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

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

yoppy0066

2015/08/01 12:34

いつもご回答頂きありがとうございます。 いまいちイメージがつかないのですが、今回の例だとどのようなコードになるのが一般的なのでしょうか?
Stripe

2015/08/01 12:41

MVCのModelは、アプリケーション・モデルなので、どんな内容のアプリケーションなのかが分からないと、コードは書けません。 ただ単に、カテゴリ分けされたメモがあるだけなら、 protocol Memo { func postMemo(text:String, category:String) var allMemos:[(text:String, category:String)] {get} } こんな感じだと思います。 ちなみに、正式にコンポーネントを作る場合は、インターフェースが必要です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問