私はQt(プログラムでのみビルドされたGUI)を使用して数か月の開発を行い、現在Cocoaを使用し始めています。私は言わなければならない、私愛ココア。 Qtで難しいと思われたことの多くはCocoaで簡単です。 Obj-CはC++よりもはるかに複雑ではないようです。
これはおそらく私だけなので、これについてどう思いますか?
CocoaはQtのWPF(それは正しいフレームワークですか?)とどのように比較されますか?
Obj-CはC#からC++とどのように比較されますか?
XCode/InterfaceBuilderはVisualStudioやQtCreatorとどのように比較されますか?
ドキュメントはどのように比較されますか?
たとえば、Cocoaのアウトレット/アクションはQtのシグナルとスロットよりもはるかに便利です。シグナル/スロットを半分の時間で回避する必要がある一方で、実際にはほとんどのGUIインタラクションをカバーしているように見えるからです。 (私はそれらを間違って使用しましたか?)
また、XCodeの標準テンプレートでは、コピー/貼り付け、元に戻す/やり直し、保存/開くなど、多くの機能が実質的に無料で提供されますが、これらはQtではかなり複雑なタスクでした。
これらの開発環境/フレームワーク/言語の少なくとも2つについて実際の知識がある場合にのみ回答してください。
私は何年にもわたってCocoa/Obj-Cのオンとオフを切り替えてきました。 2010年の時点で、WPF/NETFrameworkと比較してかなり制限されていることがわかりました。私が見つけた違いのいくつかをリストします、そしてあなたはあなた自身で判断することができます。
マークアップ言語
WPFで設計すると、非常に単純なXMLであるマークアップが得られ、自分で作成したツールを使用して簡単に手動で編集したり編集したりできます。 Cocoaでは、簡単な手動編集や操作用に設計されていないxibファイルを使用する必要があります。 WPFマークアップの簡単な例を次に示します。
<DockPanel>
<Label>Select your favorite food:</Label>
<ComboBox
SelectedText="{Binding FavoriteFood}"
SelectedItemsSource="{Binding AllFoods}" />
</DockPanel>
これはマークアップ全体であり、編集が難しい.xibの約50行に相当します。
単純なXAMLを表示および編集する機能は、次の点で非常に価値があります。
レイアウト機能
WPFでは、ウィンドウサイズの変更に応じて、パネルを使用してコントロールを自動的にレイアウトできます。スタイルを使用してコントロール間の間隔を定義するか、余白を調整して希望どおりの外観にするか、またはその両方を行うことができます。いずれの場合も、UIはフォントサイズ、ウィンドウサイズ、画面解像度の変更に自動的に適応します。 Cocoaでは、WinFormsと同様に、すべてのコントロールが特定のxおよびyの場所にあり、私ができるのは自動サイズ変更だけです。これは非常に制限的です。例えば:
WPFレイアウトの利点は、パネルにコントロールを追加し、後で正確なレイアウトを調整する方法でインテントを表現できることです。 WPFは昔ながらの方法でも機能しますが、レイアウトにパネルを使用すると、X/Yレイアウトに戻ることはありません。
たとえば、私が行った1つのアプリケーションには、星評価とコメントボックスを含む行がありました。通常、行は星評価の高さだけでしたが、テキストボックスに長いコメントを入力すると、TextBoxが高くなり、行が高くなるため、次の行が下に移動しました。 WPFを使用すると、この動作を無料で取得できました。Cocoaを使用すると、手動でコーディングする必要がありました。
データ接続
Cocoa/Obj-Cを使用すると、基本的なデータベースアクセスやファイルとの間のシリアル化など、組み込みのデータ接続にほぼ制限されます。 WPF/NET Frameworkを使用すると、UIをSunの下にある実質的にすべてのものに直接バインドできます。
実際、任意のNETFramework言語でドライバーが記述されている事実上すべてにバインドできます。100を超えるNETFramework言語があります。
繰り返しコード
Cocoaでは、モデルは.hファイルと.mファイルで構成され、コントローラーは.hファイルと.mファイルで構成され、ビューは.xibファイルで構成されます。モデル内のすべてのオブジェクトのすべてのフィールドは、これらの場所のすべてを参照する必要があります。
WPF/NETでは、通常、単一のフィールドは2行のコードにのみ表示されます。1回はモデルが定義されている場所で、もう1回はビューによって表示されます。たとえば、私のコードでは、通常、XMLで単純なモデルフィールドを定義します。
<Property Name="City" Type="string" />
次に、都市を編集するためのテキストボックスを作成するには、「City」プロパティをビューにドラッグするだけで、次のXAMLになります。
<TextBox Text="{Binding City}" />
したがって、「City」は、アプリケーション全体の2行のコードでのみ言及されています(別の「City」テキストボックスが他にある場合を除く)。ココアでは、「City」は少なくとも5回参照されます。
モデルに直接バインド
Cocoaでは、単一のコントローラーは実際には単一のビューにのみ適しています。同じモデルに対して新しいビューを作成する場合は、新しいコントローラーが必要です。 WPF/NETには、それを行うためのより良い方法がありますが、本当に必要な場合は、コントローラーを作成することもできます。
WPF/NETでは、ビューは通常、ほとんどのコントロールをモデルに直接バインドします(上記のCityの例を参照)。他のコントロールは、現在のビューに関連付けられた状態情報をモデル化する「ビューモデル」にバインドされます。あなたは、「ビューモデル」を検索している場合、両方の結果をフィルタリングし、検索テキストをHILIGHTするためにビューで使用することができますので、例えば、検索文字列が含まれます。
WPF/NETでは、コントロールの複数のプロパティをモデル(またはビューモデル)の同じ部分または異なる部分にバインドすることもできます。
<TextBox Text="{Binding AmountToTransfer}"
Background="{edf:Binding UserIsHappy ? Green : White}" />
違いは、WPFでは、ビューモデルは通常、動作が類似している複数の画面間で共有可能であるため、LOBアプリケーションでは、カスタムビューを作成するときに、1つのファイルを編集するだけです。
コマンドアーキテクチャ
Cocoaでは、ボタンはそのターゲットとアクションをビュー内のNSActionCell
に格納します。これは、特定のオブジェクト(通常はコントローラー)で特定のメソッドを呼び出すことを意味します。 WPF/NETでは、ボタンは同じように動作しますClickイベントがありますが、それはまた、あなたがコマンドを呼び出すことができますコマンドプロパティがあります。
単一のコマンドをアプリケーション全体で共有できるため、WPFのコマンドは非常に強力です。たとえば、WPF自体が削除コマンドを定義します。長い間、このコマンドへのモデルの応答などとして、あなたのビューに、「削除」ボタンを追加すると、このXAMLを作成し、[プロパティ]ウィンドウで[削除]コマンドを選択するなどの単純なようです。
<Button Command="Delete" />
これは、リストからオブジェクトを削除する機能的な削除ボタンを取得するために必要なすべてです。組み込みのDeleteコマンドにも注意してください。
コマンドは、あなたが、ほとんどのコマンドを受信するオブジェクトを指定する必要はありません一般的なアプリケーションでは、先祖オブジェクトとモデルにルーティングされます。
スタイルシート
Cocoaには、スタイルシートをパネルに適用し、設計時または実行時にパネル内のすべてのコントロールに影響を与えるメカニズムはありません。たとえば、アプリケーションは次のことを行うことができます。
WPF/NETは、スタイルを使用することにより、これらすべての操作を簡単にします。スタイルを使用して、任意のオブジェクトの任意のプロパティを設定できます。スタイルは、オブジェクトタイプによって暗黙的に設定することも、明示的に設定することもできます。次に例を示します。
<Button Style="{StaticResource DeleteButtonStyle}" />
スタイルシートは、コントロールライブラリ、アプリケーションレベル、「テーマ」に固有、ウィンドウ、特定のコントロールのリソースディクショナリ、またはコントロール上で、好きな場所に定義できます。
コントロールテンプレート
Cocoaでは、コントロールはそれぞれ独自の外観を描くため、サブクラス化する以外に、コントロールの視覚的なスタイルを変更することはほとんどできません。 WPF/NETでは、コントロールの外観はテンプレートによって提供されます。テンプレートは、考えられるほとんどすべてのものに自由に置き換えることができます。
例えば:
コントロールテンプレートとデータテンプレートも、アニメーションを内蔵含むことができるので、例えば、あなたのドアが実際にアニメーションオープンスイングすることができますし、それをクリックしたときに閉じました。これは、ExpressionBlendで行うのは簡単です。マウスを約20回クリックするだけです。 2つの線形アニメーションを作成し、それらをイベントトリガーにアタッチするだけです。
カスタムコントロール
CocoaとWPFはどちらも、既存のコントロールをサブクラス化して新しいコントロールを作成できます。 Cocoaでは、新しいコントロールは.xib /.nibファイルにシリアル化されます。 WPFでは、これらは組み込みのコントロールと同じようにXAMLの一部です。
<StackPanel>
<TextBlock>
Hello, <Run Text="{Binding FirstName}" />.
<Bold>Good morning!</Bold> How are you today?
</TextBlock>
<my:JoySelector Happiness="{Binding Happiness}" />
</StackPanel>
この例では、JoySelectorは私が定義したコントロールであり、Happinessはそのプロパティの1つです。
CocoaとWPFの大きな違いは、カスタムコントロールの描画にあります。 Cocoaでは、コントロールの外観を作成するために、描画プリミティブへの呼び出しをコーディングする必要があります。これはWPFのオプションですが、通常はコントロールテンプレートを使用するとはるかに簡単に実行できます。
たとえば、Cocoaでは次のように書くことができます。
CGSize size = CGSizeMake(30, 20);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0, 1.0, 0.0, 0.0);
CGContextFillEllipseInRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
一方、XAMLを使用するWPFでは、同等のものは次のようになります。
<Ellipse Width="30" Height="20" Fill="Red" />
またはWPFのコード(C#):
return new Ellipse { Width=30, Height=30, Fill=Brushes.Red };
もちろん、ControlTemplateには複数の項目が含まれる場合があります。
<ControlTemplate TargetType="my:JoySelector">
<Grid Width="50" Height="50">
<Ellipse Width="30" Height="20" Fill="Red" VerticalAlignment="Left" />
<Path Data="M0,0 L3,5 L8,8 L5,3 L0,0" Fill="Blue" />
<ComboBox
SelectedItem="{TemplateBinding Happiness}"
Style="{StaticResource JoySelectorBoxStyle}" />
</Grid>
</ControlTemplate>
このXAMLは通常、JoySelectorを右クリックし、[編集]> [テンプレート]> [新規作成]を選択し、描画ツールを使用して楕円、パス、およびComboBoxを描画し、[プロパティ]ウィンドウからComboBoxのバインドとスタイルを選択することでExpressionBlendで作成されます。
データテンプレート
Cocoaでは、ゲーム内の機器の在庫やさまざまな種類のアカウント(投資、マネーマーケット、貯蓄)のリストなど、さまざまな種類のアイテムのリストまたはツリーが必要な場合は、ほとんどすべて自分でコーディングする必要があります。 WPF/NETでは、DataTemplatesを使用できます。
たとえば、すべての武器に「ヒット強度」と「防御強度」がある場合、次のようなデータテンプレートを含めることができます。
<DataTemplate TargetType="game:Weapon">
<DockPanel TextElement.FontWeight="Bold">
<Image Source="{StaticResource WeaponDrawing}" />
<TextBlock Text="{Binding WeaponName}" DockPanel.Dock="Top" />
<TextBlock Text="{Binding HitStrength}" Foreground="Red" />
<TextBlock Text="{Binidng DefenseStrength}" Foreground="Blue" />
</DockPanel>
</DataTemplate>
他のゲームオブジェクトは異なるテンプレートを使用し、WrapPanelを使用してListBoxを使用してインベントリを表示し、読み取り順にレイアウトすることができます。 (WPFでは、ListBoxはその項目を垂直リストに表示する必要がないことに注意してください。任意のパネルを使用できます。)
これと同じ手法は、LOBアプリケーションでも重要です。たとえば、アプリケーション全体のDataTemplateで設定された請求書のデフォルト表現を使用できるため、請求書のリストを表示するアプリケーションの任意の部分で、それらがデフォルト形式で自動的に表示されます。 。これには、アイコン、請求書番号、追加情報を含むツールチップポップアップ、および請求書を開いたり編集したりできるコンテキストメニューが含まれる場合があります。
トリガーとアニメーション
Cocoaではアニメーションを実行できますが、アニメーションの作成と適用の両方のコードを作成する必要があります。 WPFでは、Expression Blendのタイムラインを使用してアニメーションを定義し、ビューでEventTriggersとPropertyTriggersを設定して、いつ実行するかを制御できます。ボタンを振るアニメーションを作成するには、右クリックしてタイムラインを作成し、タイムライン上のいくつかのポイントでマウスを使用してボタンの位置、回転、またはスケールを設定し、自動的に作成されたEventTriggerを目的のイベントに変更します。ボタンをトリガーします。
Cocoaにはアニメーションプロパティストアまたは強制メカニズムがないため、アニメーションによって行われた変更は永続的です。アニメーションを削除してプロパティ値を元に戻すことはできません。また、共有リソースのプロパティ(ブラシの色など)を手動でコピーせずにアニメーション化することはできません。また、範囲外の値にアニメーション化して、コントロール自体を適切な値に強制することもできません。 WPFでは、アニメーションシステムには、アニメーション値、バインド値、デフォルト値、および強制値を個別に追跡する機能があるため、これらの問題が発生することはありません。
WPFでは、ボタンのクリック、プロパティの状態の変更(モデル内のデータの変更を含む)、モデルによって生成されたイベントなどのUIイベントで実行するアニメーション、継続的に実行するアニメーション、またはコードを介して実行するアニメーションを設定できます。
WPFでは、カスタムアニメーションクラスを作成し、それらをWPFの一部であるかのようにExpressionBlendで使用できます。自分でコーディングするのではなく、組み込みのPathAnimationで使用されるGeometryオブジェクトを描画することもできます。
WPFには、本当に必要な場合にコードでアニメーションを作成して開始する機能があることに注意してください。また、Quartz Composerなどの別のアプリケーションからアニメーションを埋め込むことは、UIオブジェクトのプロパティをアニメーション化することと同じではないことに注意してください。 CocoaとWPFはどちらも、他のテクノロジで作成されたアニメーションを埋め込むことができますが、WPFを使用すると、Expression Blendを使用して、UIの任意の部分をアニメーション化するタイムラインを作成できます。
バインディングの一部としての変換
Cocoaには、NSFormatterを使用して単一の値との間で変換を行う機能があります。より複雑なことは、コントローラーで行う必要があります。 WPFでは、Cocoaの組み込みNSFormattersがカバーする単純なケースにStringFormatを使用できますが、IValueConverterまたはIMultiValueConverterを指定して、値のカスタム変換を実装することもできます。たとえば、カスタムコンバーターを棒グラフのデータ系列に追加して、棒グラフのデータ項目をターゲット値にすばやく順番にアニメーション化することができます(「ゼリー」アニメーションと呼ばれます)。 WPFのコンバーターは、一方向または双方向で使用でき、単一の値または複数の値を変換できます。
変換を使用すると、複数のプロパティまたは計算にバインドして、結果をフォーマットすることもできます。次に例を示します。
<TextBlock Text="{edf:Binding (Height + Width)/2, StringFormat=0.000}" />
この種の変換によるバインドは、Cocoaでは不可能です。
サードパーティのコントロール
Cocoaでは、通常、Cocoa用に設計されたUIウィジェットのみをアプリケーションに含めることができます。 WPFには、WPFコントロールを含めることができますが、WinForms、MFC、HTML、Java、Flash、およびその他のテクノロジを使用して開発されたUIのセクションを含めることもできます。 WPFは、マークアップシステムを使用してオブジェクトを構築し、そのプロパティを設定する場合でも、これらの他のテクノロジをWPFに直接統合するための機能を提供します。
<StackPanel>
<TextBlock>Here is a WinForms control:</TextBlock>
<WindowsFormsHost>
<tools:LegacyChartingControl
Width="20" Height="30"
Title="Graph of something"
SeriesXMin="0"
SeriesXMax="10" ... />
</WindowsFormsHost>
</StackPanel>
外部で作成されたメディア
CocoaとWPFの両方に、サードパーティのツールで作成されたビデオ、アニメーション、ビットマップなどのメディアを含めることができます。各環境は、基盤となるオペレーティングシステムでサポートされているそのようなすべてのメディアタイプをサポートしています。 WPFは、メディアの制御に関してCocoaよりも少し多くの機能を提供します。たとえば、ボタンのコマンドを「MediaCommands.NextTrack」または「MediaCommands.FastForward」に設定すると、メディアは自動的に適切に応答します。また、WPFは、メディアの非同期読み込みにいくつかの改善を提供します。
WPF(Silverlight経由)は、完全にクロスプラットフォームの方法でいくつかの高品質のビデオおよびオーディオコーデックもサポートしているため、任意のプラットフォームで動作するメディアに依存できます。
Illustratorなどのツールで作成された図面やFlashなどのツールで作成されたアニメーションをネイティブのWPF図面やアニメーションに変換して、それらのプロパティを操作およびデータバインドできるツールもあります。たとえば、Flashで作成されたバウンドするボールのアニメーションを取得し、そのY座標を遠地点でデータバインドして、モデルのデータ値に基づいてボールが上下にバウンドするようにすることができます。
ガベージコレクション
2007年現在、ガベージコレクションはCocoa/Obj-Cでようやくサポートされていますが、多くのライブラリではまだ処理できないため、今日作成されているCocoaコードのほとんどは、参照カウントを使用した手動メモリ割り当てを使用しています。したがって、今日でも、Cocoaコード全体に多くの「[abcrelease]」が散りばめられています。 WPF/NETは初日からガベージコレクションを行っているため、この問題は発生しません。
Webブラウザ内での実行
現在、Cocoaアプリケーションはデスクトップアプリケーションとしての実行に制限されていますが、WPFは、XBAPまたはSilverlightテクノロジを使用して、デスクトップと同じようにWebブラウザー内で簡単に実行できます。
クロスプラットフォーム機能
ここでの話は似ています:
CocoaアプリケーションはMacOS Xでネイティブに実行され、CocotronまたはGNUstepを使用して機能のサブセットに制限することにより、WindowsおよびLinuxでも実行できます。
WPFアプリケーションはWindowsでネイティブに実行され、Silverlightを使用して機能のサブセットに制限することにより、Mac OSXおよびLinuxでも実行できます。
唯一の重要な違いは、Silverlightはブラウザーで実行でき、CocotronやGNUstepよりもはるかに優れたベンダーサポートとツールを備えていることです。
WPFの他の高度な機能
これまでのところ、WPF/NETにもないCocoaの機能は見つかりませんでしたが、たとえば、CocoaにないWPF/NETの機能はたくさん見つかりました。
サードパーティのアルゴリズムとドライバー
Cocoa/Obj-Cは、C呼び出し規約を使用するプリコンパイル済みライブラリを呼び出し、特定の他の言語で定義されたオブジェクトに対してinvokeメソッドを呼び出すことができます。これは、アプリケーションに統合する必要があるサードパーティのコードには、通常、CスタイルのAPIが必要であることを意味します。 WPF/NETは、100以上の言語で記述されたコードをアプリケーションに直接含めることができ、すべての機能に直接アクセスできます。さらに、C、C++、COM、DCOM、Webサービス、およびその他の呼び出し規約を使用して、他の言語で記述されたプリコンパイル済みコードを呼び出すこともできます。さらに、NETFrameworkコードが他のさまざまな言語やシステムを直接呼び出すことができるオープンソースのシムがあります。つまり、WPFアプリケーションでは、デバイスドライバーを含むサードパーティのコードに接続するために、ごく少量のグルーコードを含める必要はほとんどありません。
言語比較
Objective-CとC#の比較は主要なタスクであり、私は試みません。バージョン4.0の時点で、C#にはObjective-Cのすべての機能と、さらに多くの機能が含まれていると言えば十分です。私は1989年にObjective-Cを学びました。これは、C#が考案されるずっと前のことですが、当時は驚くほど強力な言語でした。今、私がそれを使用するとき、特にLINQとGenericsを失って、私はうんざりします。
Objective-Cでこの種のデータ変換を試してください。
DataContext =
from lesson in AllLessons
where lesson.Active
groupby lesson.Category into category
select new
{
categoryName = category.Key.Name,
lessonsInCategory =
from lesson in category
select new
{
lesson,
fullName = lesson.ShortName + " " + lesson.Suffix,
priority = Rand.Next(10)
}
};
AllLessonsが動的に提供される場合、この結果をWPFに直接バインドできます(<ListBox ItemsSource="{Binding}" />
)そしてそれをリアルタイムで動的に更新させます。
LINQをC#で使用すると、結合や並べ替えなども実行できます。作成するバックエンドコードはまったくありません。また、Visual StudioのIntelliSenseを使用すると、編集時にプロパティの名前などを完成させ、間違いを強調することもできます。
Objective-CとC#の良い比較はわかりませんが、ウィキペディアではC#とJava)の間に良い比較があり、Objectiveにも欠けているC#の機能の多くを呼び出しています。 -C。
言語バインディング
CocoaはObjective-Cに制限されておらず、WPFはC#に制限されていません。どちらも他の多くの言語からアクセスできます。違いは、CocoaはObjective-Cを中心に構築されているため、別の言語から使用すると非常に厄介になる可能性があることです。たとえば、アクションは、Javaまたは他の言語とは非常に異なるセマンティクスを持つObjective-Cメソッド呼び出しになります。一方、WPFは、特別なC#機能を必要としないように意図的に設計されているため、他の言語から簡単に使用できます。たとえば、Java(真のプロパティがない)で使用する場合、PropertyDescriptorは代わりにgetメソッドとsetメソッドを使用します。
さらに、NET Framework上に構築されているため、WPFアプリケーションは、複数の言語でコーディングされたオブジェクトとライブラリに対して同時に機能します。つまり、優れたC++、Haskell、またはRubyアルゴリズムの実装を見つけた場合は、選択した言語にコードを書き直すことなく、コードを簡単に使用できます。Cocoaでは、通常、コードを書き直す必要があります。 Objective-Cとして、または他の言語を呼び出すためのシムコードを作成します。
共通の利点
WPFと共有する競合他社に対するCocoaのいくつかの利点は次のとおりです。
最終メモ
CocoaをWPFと比較するときは、InterfaceBuilderをVisualStudioではなくExpressionBlendと比較する必要があります。 Visual Studioはコードの記述には問題ありませんが、私の意見では、Expression Blendはユーザーインターフェイスを設計するためのonlyツールです。
実際のアプリケーション開発では、WPFとCocoaの主な違いは、一般的にnotWPFのより強力なグラフィックス機能です。これらはCocoaアプリケーションに含めることができるためです。それらを手作業でコーディングすることによって。主な違いは、データバインディングと、model-view-controllerからmodel-view-viewmodelへの進化であり、これにより、WPFは実際にアプリケーションを開発するのに非常に効率的になります。
私は最近Cocoaをあまり使用していないので、上記の説明で最近のCocoaの改善を見逃した可能性があります。何らかの形でCocoa(またはそのことについてはWPF)に不公平であった場合は、コメントを追加して、私が見逃したことを知らせてください。
これはそれを見る一つの方法です。反対側を聞くと、これはかなり良い読み物になると思います: http://arstechnica.com/Apple/news/2008/04/what-Microsoft-could-learn-from-Apple.ars
個人的には、パフォーマンスも考慮する必要があると思います。 Objective-Cと以前のNeXTSTEPライブラリははるかにコンパクトに見えますが、WPFは少しやり過ぎです。