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

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

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

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

iOS

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

Xcode

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

Swift

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

5422閲覧

[Objective-C][Swift]関数の呼び出し元と呼び出し先で名前が違うのに実行される

reishisu

総合スコア39

Objective-C

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

iOS

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

Xcode

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

Swift

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/03/08 23:03

編集2020/03/08 23:19

前提・実現したいこと

Objective-CもSwiftも初心者なので漠然とした質問になってしまいますが、、、

先日SwiftからObjective-Cの関数を呼び出すようにしており、その時には気がつかなかったのですが、SwiftでexportItem(toId: songId.description)と関数を実行してて、それなのにexportItemToId:(NSString *)songidが呼び出されておりました。
イメージ説明

やりたいことは、exportItemToId:(NSString *)songidで間違い無いので問題は無いのですが、入力保管でもexportItemが出てきてしまい、理解できません。
ヘッダーファイルも作成しており、そこでもexportItemToIdと宣言しています。

なので、どのような仕組みで関数名が違うのに実行できているのか教えて頂きたいです...

該当のソースコード

ViewController.swift
全文だと長いので、関係ない部分を削除しております。

Objective

1//import Foundation 2import UIKit 3import MediaPlayer 4import AVFoundation 5 6class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 7 8 let instanceOfObjcMethod: ObjcMethod = ObjcMethod() 9 10 // 選択した音楽を再生 11 func tableView( _ tableView: UITableView, didSelectRowAt indexPath:IndexPath ) { 12 13 // soundIdからMediaItemを取得 14 let songId: NSNumber = albums[indexPath.row].songId 15 print("expotItemを呼び出します") 16 instanceOfObjcMethod.exportItem(toId: songId.description) 17 print("expotItemを呼び出し終わりました") 18 } 19} 20

ObjcSwift.h

Objective

1#import <Foundation/Foundation.h> 2 3#ifndef ObjcSwift_h 4#define ObjcSwift_h 5 6@interface ObjcMethod : NSObject 7 8- (BOOL) exportItemToId: (NSString*) songId; 9- (void) setDoDisplay: () _ ; 10 11@end 12 13#endif /* ObjcSwift_h */

Unity-iPhone-Bridging-Header.h

Objective

1#import <Foundation/Foundation.h> 2#import <UIKit/UIKit.h> 3#import "UnityInterface.h" 4 5#import "ObjcSwift.h"

MusicLibraryMediaPicker.mm
全文だと長いので、関係ない部分を削除しております。

Objective

1 2# import "ObjcSwift.h" 3 4extern "C" { 5 BOOL exportItem (MPMediaItem *item); 6 7 /******************************** 8 * クラスを作って処理している 9 ********************************/ 10 @implementation ObjcMethod: NSObject 11 12 /************************************** 13 * 曲IDをもとにエクスポートする関数 14 * @param songId エクスポートしたい曲ID 15 * @return エクスポートが完了したらYESを返す 16 **************************************/ 17 - (BOOL) exportItemToId: (NSString*) songId { 18 NSLog(@"!!!!!!!!exportItemToId呼ばれたよ!!!!!!!"); 19 // char*型の文字列を変換 20 NSString* s_id = [NSString stringWithFormat:@"%@",songId]; 21 MPMediaQuery* songQuery = [MPMediaQuery songsQuery]; 22 [songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithBool:NO] forProperty:MPMediaItemPropertyIsCloudItem]]; 23 NSArray *songlists = songQuery.collections; 24 for (MPMediaItemCollection *songlist in songlists) { 25 MPMediaItem *representativeItem = [songlist representativeItem]; 26 NSString* PersistentID = [NSString stringWithFormat:@"%@", [representativeItem valueForProperty:MPMediaItemPropertyPersistentID]]; 27 if ( ![representativeItem hasProtectedAsset] && [s_id isEqualToString:PersistentID] ) { 28 sid = [[representativeItem valueForProperty:MPMediaItemPropertyPersistentID] longValue]; 29 sname = [representativeItem valueForProperty:MPMediaItemPropertyTitle]; 30 albumArtwork = [representativeItem.artwork imageWithSize:representativeItem.artwork.bounds.size]; 31 NSLog(@"見つかりました!"); 32 NSLog(@"セットします!![sid:%ld, sname:%@]:", sid, sname); 33 return YES; 34 } 35 } 36 return NO; 37 } 38 @end 39}

実行結果

expotItemを呼び出します 2020-03-09 07:06:42.756224+0900 SoundStory[343:9123] !!!!!!!!exportItemToId呼ばれたよ!!!!!!! 2020-03-09 07:06:42.772364+0900 SoundStory[343:9123] 見つかりました! 2020-03-09 07:06:42.772549+0900 SoundStory[343:9123] セットします!![sid:6821698684411020667, sname:ココロ自由宣言]: expotItemを呼び出し終わりました

初歩的な質問で恐縮ですがよろしくお願い致します????‍♂️????‍♂️

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

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

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

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

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

guest

回答1

0

ベストアンサー

Swift のメソッド名 exportItem(toId:) は Objective-C の exportItemToId: に対応します。

Swift と Objective-C の間のメソッド名の対応関係ですが、Swift 1.0 の頃のものが
Using Swift with Cocoa and Objective-C - それはBooks
Swiftでメソッドの命名時に引数のルールに迷ったら見直すメモ - Qiita
Objective-CとSwiftの組み合わせ方のまとめ
Objective-CとSwiftの組み合わせ方のまとめPart2
に書いてあり、その後の変更点は
ObjCとSwift3が混在するプロジェクトでメソッド名にWith~がついてObjC側からSwiftのメソッドが見られない時の対策 - Qiita
などにありますが、現状のまとまった解説は見当たらない(たぶんみんなもう移行済み)ですね…。

投稿2020/03/09 02:29

hoshi-takanori

総合スコア7893

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

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

reishisu

2020/03/09 06:15

回答して頂き、ありがとうございます! やはり対応していますよね...(>_<) 一応、一通り貼って頂いたサイトを確認したのですが、 http://hamasyou.com/blog/2014/06/27/apple-swift-cocoa-objective-c/ では、Methodsは「Objective-C のメソッド名がそのまま Swift のメソッドになり、第一引数名が省略される。残りの引数名はそのまま残る。」 と書かれており、 https://qiita.com/yimajo/items/90153ceed878c46eaeda の外部引数名を指定する例では、 Withが勝手に入ってくると記載されており、更に悩んでしまいました…???? ちなみに私のSwiftのバージョンは4.2で もしかして、Swift4.2ではBridging-Headerに書かれている関数名がexportItemのように、最初に出てくるItemのような大文字から始まる単語1つまでが関数名になり、2番目以降に出てくるToIdは無視されるような仕様なのでしょうか??
hoshi-takanori

2020/03/09 06:23

言葉足らずでごめんなさい。現在の Swift(たしか 3 以降)では第一引数名も省略されることはなくなって Swift の exportItem(toId:) は Objective-C の exportItemToId: に対応するようになりました。第一引数名を省略したい場合は exportItem(_ toId: ... ) みたいに _ を入れます。
reishisu

2020/03/09 10:08

私の方こそ理解力が乏しくて申し訳ないです...???? 多分、また同じ質問になってしまい恐縮ですが、、、 私の勘違いでなければ、Objective-Cのファイルを先に作成しており後からSwiftのファイルを作成したのですが、その際にexportItemToId第一引数はsongIdで、Swift側で呼び出した時にはexportItemToId(songId: "文字列")となるのかなぁと思っておりました???? なので、これはObjective-Cが先に作成されたとしても、Swiftで利用する際には元々あった引数のsongIdを削除して、exportItem(toId:)をexport(ItemToId:)のように書いても同じように動作するのでしょうか?(>_<)
hoshi-takanori

2020/03/09 10:22

export(itemToId:) は exportWithItemToId: になりますが、exportItemTo(id:) だと exportItemToId: ですね。メソッド(関数)名と第一引数名をくっつける時、メソッド名の最後か第一引数の最初が前置詞だとそのままくっつけて、そうでなければ勝手に With が入るようです。あと、第一引数の最初の文字は大文字になります。
reishisu

2020/03/09 10:38

なるほどです! Swiftが勝手に前置詞を挟もうとしていたんですか???? なので、今回はたまたまObjective-CでexportItemToIdと前置詞のToが入っていたので、自動的に第一引数のsongIdがToId(またはId)に置換されていたんですね!! では、もし今回の関数名が前置詞抜きのexportItemId: (NSString*) songIdだとしたら、Swiftで呼ばれた際にexportItemIdWith(SongId: "文字列")になるという認識で大丈夫でしょうか? あ、第一引数の頭文字は大文字にしないといけないのですね、とても勉強になります(>_<)
hoshi-takanori

2020/03/09 10:46

えっと、Swift の名前と Objective-C の名前の自然な対応は n:1 になると思います。たとえば、Swift の exportItem(toId:) と exportItemTo(id:) と exportItemToId(_ id:) はどれも Objective-C では exportItemTo(id: になります。 で、Objective-C で exportItemId: になる Swift の名前は exportItemId(_ id:) しかないと思います。もっとも、Objective-C の名前をどうするかは @objc() をつけて指定できるので、なんとでもなりますが。 あと、第一引数の最初の文字ですが、Swift 側では小文字にするのが普通です。Objective-C 用にメソッド名とくっつける時に勝手に大文字にしてくっつけるということになります。
reishisu

2020/03/09 11:57

う〜ん、今の説明でなんとなく理解かもしれませんが自信がないです...???? Objective-Cの関数をSwiftで呼び出しする際に、Swiftでは関数名の最後または第1引数の外部引数名の先頭が前置詞になっている組み合わせであれば、たくさんの表現する方法があるために Swift : Objective-C = n : 1 ということでしょうか(>_<) SwiftでObjective-Cの関数を呼び出した際に、呼び出し方が複数あることは多分理解できましたが、Objective-Cの引数にいたsongIdが急にいなくなってしまうのが、いまいち理解に苦しみます... あ、私がどうにかするとかではなく、Swift→Objective-Cへ変換する際に自動でやってくれるんですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問