ラベル Objective-C の投稿を表示しています。 すべての投稿を表示
ラベル Objective-C の投稿を表示しています。 すべての投稿を表示

2013年5月16日木曜日

関数の構文が分け分かんない件

例えば、MidiSend関数は次のように宣言されているのだが、


extern OSStatus
MIDISend( MIDIPortRef port, 
MIDIEndpointRef dest, 
const MIDIPacketList * pktlist ) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_4_2);


え?この構文(関数パラメータの括弧とじと文末のセミコロンの間)って何?ということで探しまわること数時間。その言わんとしている意味は何となく分かるのだが、書き方が許せないをモチベーションに、重い腰を上げてStackoverflowで検索してみると、


http://stackoverflow.com/questions/4924285/how-to-deprecate-a-method-in-xcode

にその答えが。

そのものズバリの話ではないが、この回答欄にある、deprecated用のgccの構文というところが答え。このケースでは、これを呼ぶんだとき、deprecated条件に一致すると、warningが出力される。

llvmじゃないの?と思ったが、歴史の古さからはgccだろう。

それはいいとして、そもそも例えば、

__AVAILABILITY_INTERNAL__IPHONE_6_1

のような定義がどこに定義されているのか、見つからない。__OSX_AVAILABLE_STARTINGが定義されている、"Availability.h"を見ても特に何も#includeされてないようだし。。と思ったが、よく見ると、先頭ではなく、中途半端なところに、"AvailabilityInternal.h"が#includeされていて、その中に__AVAILABILITY_INTERNAL__IPHONE_6_1などがずらずらと定義されており、

__attribute__((availability(ios,introduced=4.1,deprecated=6.1)))

のように書いてあった。

まあそれにしても、勝手にこういう構文が追加になって人が持ってたK&R読んだことがある自分にメールの1つもよこさないってどういうこと?

2013年2月27日水曜日

@synthesizeを省略する

windowが、というか、xcode(ver 4.5.2)でempty applicationを新規作成すると、作成されるスケルトンの中で、そう例えば application:didFinishLaunchingWithOptions:の中で、


    [self.window makeKeyAndVisible];


みたいにプロパティが使われている。
これを直接インスタンス変数に変えてみようとすると、あれ? _windowがない。というか、windowの@syznthesizeがない。かといって


    [window makeKeyAndVisible];

だとエラーになる。まさか、

    [_window makeKeyAndVisible];

だと通るの?

通るんですよお客さん。

がしかし、全部のプロパティが@synthesizeが無いわけでもない。試しに1個消してみると、undefinedになる。えーまさかのwindowだけ? なわけないよないくらなんでも。論理が通らない。

何だろう?と暫し悩み、ググるも、色よい答えが見つからず、xodeの4.4辺りから@synthesizeが省略できる、という話は見かけるものの、そこまで。
でよーくコードを見ると、window以外のプロパティには readonly が付いている。

「これ?」

はい、それです。readonlyを取ると、他のプロパティも@synthesizeなしでOK。もちろんインスタンス変数名は「_プロパティ名」となる。

readonlyを付けると、自分の見間違えで、設定するところだけエラーになるのかと思ったが、間違いなく参照個所すべてが"undecleared"になる。

変なの。

2012年7月31日火曜日

プライベートメソッドをClass Extensionではもう古い

()は実はもうとっくに終わっていた。

WWDC2012の"Modern Objective-C"というスライド(ダウンロード済み)。
http://adcdownload.apple.com//wwdc_2012/wwdc_2012_session_pdfs/session_405__modern_objectivec.pdf

直接ブラウザのURLにつっこんだらエラーになったので、セッション名でググって出てきたここから行ったらうまく取れた。理由はよく分かっていない。

この中で、例題に挙げられているクラス名が渋い。"SongPlayer" でっせ〜?こういうところは見習わないとねえ。すごいすごい。

で、バージョンはよく知らないのだが(そして礼儀正しいプログラムに対して不躾だが)、今はこのカテゴリもどきのClassExtensionを使わずとも、@implementation〜@endの間、かつ、参照するメソッドの下に入れるのがBest Solutionらしい。

が、Okay WorkaroundでClassExtensionの中にPropertyを入るケースが紹介されている。これはどうなんだろう?Best Solutionには@interface側が書いてないので分からない。多分、今まで通り.hに@interfaceを書いて、プロパティやインスタンス変数(あれば)はそちらにということかな。

本質的には@privateがメソッドに当てられないってことだと思うのだが、逆にこうして(Cで言う)プロトタイプ宣言なしでプライベートメソッドを書けるほうが楽なのだし、例えば@privatemethodというディレクティブがあったとしたらどっちを使うか?と言われればそこはかなり微妙(ケースバイケース、ワンバイワン)だと思う。ただ短絡的には@classがあるんだから、どうして”短絡的に"@privatemethodとか@methodといったディレクティブを取り入れなかったのだろう?と思うと、それは恐らく@classほど使い出がないからじゃないだろうか。

他にもプロトコルを後で()追加しているとあるコードがあるが、これもなあ。要するにあちこちに書かないほうがいいと自分は思う。



()

@interface MidiInterface () <MidiCodec>
@end

みたいなクラス名のうしろの()(括弧括弧)は空のカテゴリって何?って思って探しまくったら無名カテゴリとか呼ばれる?"Class Extensions"なるプライベートメソッドなんかを書く方法らしい。