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

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

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

Xcode 7は、ソフトウェア開発のためのアップルの統合開発環境であるXcodeのバージョン。UIを作成するために用いるグラフィカルツールです。iOS9/OS X El Capitan/watchOS2に対応。Swift 2コンパイラーが搭載されています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

3回答

2067閲覧

swiftのprotocolに関して{ get } なのに値をセットできる

keys

総合スコア215

Xcode 7

Xcode 7は、ソフトウェア開発のためのアップルの統合開発環境であるXcodeのバージョン。UIを作成するために用いるグラフィカルツールです。iOS9/OS X El Capitan/watchOS2に対応。Swift 2コンパイラーが搭載されています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2017/11/29 06:19

protocolの実装で、理解ができない部分があり、下記のような実装ではvar name:はsetなので、新たに値を代入できないことになるのでは?と思うのですが、下記の実装では、 var name:に値が代入できてしまいます。

セットとかゲットとかの考え方が間違っていると思われますが、よければこの部分に関してアドバイスください。

@objc protocol MyDataSource { // 継承先でgetのみ(readonly)なプロパティを実装する var name: String { get } // 継承先でget/set両方可能なプロパティを実装する var vintage: Int { get set } } class ViewController: UIViewController, MyDataSource { //ここで値をセット var name: String = "" var vintage: Int = 0 override func viewDidLoad() { super.viewDidLoad()

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

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

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

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

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

guest

回答3

0

protocol の宣言でのプロパティの { get }はこのプロトコルに準拠していれば{ get }が出来ます。という宣言であり、
プロトコルに準拠したクラスなどがそのプロパティを代入可能なプロパティとして宣言することは問題ないです。

例えば以下のように、MyDataSourceにキャストするとMyDataSourceのnameプロパティはsettableではないのでエラーとなります。

swift

1 2let vc = ViewController() 3ve.name = "なにか" // OK ViewControllerのnameプロパティはsettable 4 5let dataSource = vc as MyDataSource // MyDataSource にキャスト 6dataSource.name = "なにか" // コンパイルエラー MyDataSourceにnameプロパティはsettableではない 7

投稿2017/11/29 07:02

編集2017/11/29 07:18
MasakiHori

総合スコア3384

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

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

0

投稿2017/11/29 06:25

tkturbo

総合スコア5572

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

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

0

ベストアンサー

{ get }は、「protocolを付加したクラス」を利用するクラスからは、読み込みしかできない、ということです。

 あまり良い例ではないですが、tkturboさんが作成したViewControllerを他のクラスがViewControllerとして定義するか、MyDataSourceで定義するかでアクセス権が変わってくるサンプルです。

Swift

1class Other { 2 init() { 3 var controller: ViewController = ViewController() 4 controller.name = "Name" // エラーなし 5 6 var dataSource: MyDataSource = ViewController() 7 dataSource.name = "Name" // エラー 8 } 9}

投稿2017/11/29 07:12

AOKINAO

総合スコア268

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

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

keys

2017/11/29 07:37

非常に分かりやすいです。「protocolを付加したクラス」を利用するクラスからは、読み込みしかできない <- なるほど。。。 「protocolを付加したクラス」を利用するクラスで、get要素に値を代入できないようにするんですね。 でも、どうせだったら、「protocolを付加したクラス」でget要素に値を代入できないようにしていただいた方が、色々分かりやすいし、使い所増えそうな気がするんですが。。。 どうして、「protocolを付加したクラス」を利用するクラスで、get要素に値を代入できないように... なんて仕様にしたのか少し疑問です 実際、使い所はあるんでしょうか。
keys

2017/11/29 07:44

``` import UIKit @objc protocol MyDataSource { // 継承先でgetのみ(readonly)なプロパティを実装する var name: String { get } // 継承先でget/set両方可能なプロパティを実装する var vintage: Int { get set } } class ViewController: UIViewController, MyDataSource { //ここで値をセット var name: String = "" var vintage: Int = 0 override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } class Other { init() { var controller: ViewController = ViewController() controller.name = "Name" // エラーなし var dataSource: MyDataSource = ViewController() dataSource.name = "Name" // エラー } } ```
AOKINAO

2017/11/29 08:12 編集

protocolという英単語に、2者間の取り決め、といった意味があります。ですから、「protocolを付加したクラス」と「それを利用するクラス」との間の関係(読み書き可能なプロパティや関数など)を決めたものがprotocolになります。  つまり、「protocolを付加したクラス」を制限したい、という目的にはそもそも向かないわけです。  そして、「protocolを付加したクラス」でget要素に値を代入できないようにしたい場合は、単にプロパティをletで宣言すれば良いだけです。  また、protocolを雛形のつもりで利用していたのでしたら、protorolよりもclassの継承の方が向いていると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問