Cocoa与Microsoft,Qt相比怎么样? [英] How does Cocoa compare to Microsoft, Qt?

查看:373
本文介绍了Cocoa与Microsoft,Qt相比怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了几个月的开发与Qt(编程GUI编程只)和我现在开始使用Cocoa。我不得不说,我可可。很多似乎很难在Qt的东西很容易与可可。 Obj-C似乎比C ++复杂得多。



这可能只是我,所以:你觉得这个吗?



Cocoa与WPF(就是正确的框架?)相比,如何与Qt?比较?

Obj-C如何比较C#到C ++?

XCode / Interface Builder与Visual Studio到Qt Creator比较?

如何比较文档?



例如,我发现Cocoa的Outlets / Actions远比Qt的信号和插槽更有用,因为它们实际上似乎覆盖大多数GUI交互,而我不得不在信号/插槽工作一半时间。 (我只是使用它们错了吗?)

此外,XCode的标准模板给我复制/粘贴,撤消/重做,保存/打开和很多其他东西几乎免费,而这些都是相当复杂任务在Qt。



请只回答如果你有至少两个这些开发环境/框架/语言的实际知识。

解决方案

多年来,我一直与Cocoa / Obj-C合作。截至2010年,我发现它相比WPF / NET框架相当有限。



标记语言



当我在WPF中设计时,我得到的标记是非常简单的XML,我可以轻松地手工编辑或编辑使用我自己写的工具。在Cocoa中,我必须使用xib文件,这不是为了方便手工编辑或操作而设计的。下面是一个WPF标记的简单例子:

 < DockPanel> 
< Label>选择您最喜欢的食物:< / Label>
< ComboBox
SelectedText ={Binding FavoriteFood}
SelectedItemsSource ={Binding AllFoods}/>
< / DockPanel>

这是整个标记,相当于大约50行难以编辑的.xib 。



查看和编辑简单XAML的能力对于:




  • 直接手动编辑

  • 与同伴沟通(例如StackOverflow)

  • 来源控制

  • 搜寻

  • 自动转换



布局功能



在WPF中,我可以使用面板来随着窗口大小的变化自动布局我的控件。我可以使用样式来定义我的控件之间的间距,或者我可以调整边距以获得我想要的精确外观,或两者。在任一种情况下,我的UI会自动调整为字体大小,窗口大小和屏幕分辨率的更改。在Cocoa中,所有控件都在特定的x和y位置,就像WinForms一样,我可以做的只有自动调整大小。这是极其有限的。例如:




  • 控件无法在窗口变小时绕回到新行或列(WrapPanel)

  • 控件无法根据可用空间添加/删除详细信息

  • 控件不能移动,为控件添加更多文本的空间。

  • 控件不能选择性缩小或放大以填充可用空间

  • Interface Builder最初设置控件以符合界面准则,但应用新样式不能更改布局。



WPF布局的优点是您可以通过向面板添加控件的方式来表达您的意图,然后调整精确布局。注意WPF也可以以老式的方式工作,但一旦你使用面板布局,你永远不会回到X / Y布局。



例如,一个应用程序我有行包含星级评分加评论框。通常,该行只是星级的高度,但是当文本框中输入长的提交时,TextBox变得更高,这使得行更高,因此以下行向下移动。有了WPF,我就可以免费获得这种行为了 - 用Cocoa我不得不手动编写代码。



数据连接 b
$ b

对于Cocoa / Obj-C,你非常局限于内置的数据连接,包括基本的数据库访问和文件的序列化。使用WPF / NET Framework,你可以直接绑定你的UI几乎任何东西在阳光下,包括:




  • 关系数据库)

  • 对象数据库(Objectivity,Versant等)

  • 旧数据库(Access,dBase,R:Base等)

  • 大型机上的COBOL数据库

  • 专有数据库格式(数百)

  • 网页

  • Web服务(SOAP,REST等)

  • XML文件

  • 平面文件(逗号分隔,制表符分隔,固定宽度) >
  • 办公文件(Word,Excel等)

  • OpenOffice文件

  • PDF表单栏位

  • GPS接收器数据(当前位置)

  • 物理开关,按钮,手柄,旋钮,滑块等位置

  • 时间本地或网络)

  • 性能计数器(CPU利用率等)

  • 摄像机(摄像机,网络摄像机,静止图像摄像机等) li>
  • 模拟电子输入

  • MIDI(乐器键盘,拾音器等)

  • OBD-II )

  • LDAP和Active Directory(用户帐户信息)

  • WBEM和SNMP(网络设备状态和配置)



事实上,你几乎可以绑定任何有任何.NET Framework语言编写的驱动程序,并且有超过一百种.NET Framework语言。



重复代码



在Cocoa中,您的模型由.h和.m文件组成,您的控制器由.h和.m文件组成,您的视图由.xib文件组成。



在WPF / NET中,单个字段通常只出现在两行代码中:一次定义模型的地方,一次它被视图呈现。例如,在我的代码中,我通常在XML中定义简单的模型字段:

 < Property Name =CityType = string/> 

然后创建一个文本框来编辑城市我只需将城市属性拖到我的视图并结束此XAML:

 < TextBox Text ={Binding City}/> 

所以City在我的整个应用程序中只提到两行代码城市文本框在其他地方)。在可可城市将被引用至少五次。



直接绑定到模型



在Cocoa中,单个控制器真的只适用于单个视图:如果为同一个模型创建一个新视图,则需要一个新的控制器。在WPF / NET有一个更好的方法来做,虽然你仍然可以创建控制器,如果你真的想要。



在WPF / NET视图通常将其大部分控件直接绑定到模型(参见上面的我的城市示例)。其他控件将绑定到一个视图模型,该模型与当前视图相关联的状态信息。例如,如果您正在搜索视图模型将包含搜索字符串,因此它可以由视图使用过滤结果和高亮搜索文本。



在WPF / NET中,您还可以将控件的多个属性绑定到模型(或视图模型)的相同或不同部分:

 < TextBox Text ={Binding AmountToTransfer}
Background ={edf:Binding UserIsHappy?Green:White}/>不同的是,在WPF中,视图模型通常可以在几个屏幕之间共享,这些屏幕的行为是相似的。 ,因此在创建自定义视图时,在LOB应用程序中所有您需要做的就是编辑单个文件。



命令结构

>

在Cocoa中,一个按钮将其目标和动作存储在视图中的 NSActionCell 中,这意味着它将调用特定的方法对特定对象(通常是控制器)。在WPF / NET中,一个按钮有一个Click事件,它的工作方式相同,但它也有一个Command属性,允许你调用一个命令。



WPF中的命令非常强大,因为单个命令可以在整个应用程序共享。例如,WPF本身定义了一个Delete命令。只要您的模型响应此命令,向视图中添加删除按钮就像在属性窗口中选择删除命令一样简单,这将创建此XAML:

 < Button Command =Delete/> 

这是所有你需要做的,以获得一个功能删除按钮,从列表中删除对象。请注意内置的Delete命令:




  • 键盘上的Delete键有键绑定

  • 提供与语言相对应的文字(删除或Eliminar或Löschen或Supprimer或...)

  • 包含说明性工具提示



命令被路由到祖先对象和模型,因此在典型的应用程序中,几乎不需要指定哪个对象接收到命令。



样式表



在Cocoa中,没有机制可以将样式表应用于面板,面板中的所有控件,无论是在设计时还是在运行时。例如,应用程序可能希望:




  • 将给定区域中的所有文本框设置为只读

  • <
  • 将所有组合框设为浅绿色背景

  • 在一组按钮之间添加均匀间距

  • 对一组复选框使用大的绿色复选标记

  • 向所有列表添加删除按钮

  • 将所有删除按钮显示为红色刷了X而不是传统的按钮

  • 在多个单独的项目上进行相同的设置



WPF / NET通过使用样式使所有这些操作变得简单。您可以通过样式设置任何对象的任何属性。样式可以通过对象类型或显式地隐式设置,例如:

 < Button Style ={StaticResource DeleteButtonStyle} > 

样式表可以随意定义:在控件库中,在应用程序级别,特定于a主题,在窗口上,在特定控件的资源重命名中,或直接在控件上。



控制模板

在Cocoa中,除了子类化之外,你不能改变控件的视觉样式,因为它们各自绘制自己的外观。在WPF / NET中,控件的外观由其模板给出,可以用任何你可以想到的任何形式自由替换。



例如:




  • 您可以在下拉菜单中使用ListBox,并将其设置为常规菜单项(具有当前选定项旁边的复选框) / li>
  • 您可以将TreeView更改为ListBoxes而非树状结构

  • 您可以更改滑块的缩略图符号或卡通角色,取决于您的目标受众(向前和向后滑动灯泡或米老鼠)

  • 您可以更改滑块以显示为旋钮或遵循非线性路径

  • 您可以更改复选框以显示为点击/点击关闭按钮,打开和关闭的锁定图标,或打开和关闭的门



控制模板和数据模板还可以包括内置动画,例如您的门实际上可以动画摇摆打开和关闭,当您点击它。这在表达式混合中很简单:它需要大约20次鼠标点击。只需创建两个线性动画并将其附加到事件触发器即可。



自定义控件



Cocoa和WPF都允许你对现有控件进行子类化以创建新控件。在Cocoa中,新控件被序列化为.xib / .nib文件。在WPF中,它们是XAML的一部分,就像内置的控件:

 < StackPanel> 
< TextBlock>
Hello,< Run Text ={Binding FirstName}/> ;.
< Bold>早上好!< / Bold>你今天好吗?
< / TextBlock>
< my:JoySelector Happiness ={Binding Happiness}/>
< / StackPanel>

在这个例子中,JoySelector是一个我定义的控件,而Happiness就是它的一个属性。 p>

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 =30Height =20Fill =Red/& 

或在代码(C#)中的WPF中:

  return new Ellipse {Width = 30,Height = 30,Fill = Brushes.Red}; 

ControlTemplate当然可以有多个项目:

 < ControlTemplate TargetType =my:JoySelector> 
< Grid Width =50Height =50>
< Ellipse Width =30Height =20Fill =RedVerticalAlignment =Left/>
< Path Data =M0,0 L3,5 L8,8 L5,3 L0,0Fill =Blue/>
< ComboBox
SelectedItem ={TemplateBinding Happiness}
Style ={StaticResource JoySelectorBoxStyle}/>
< / Grid>
< / ControlTemplate>

此XAML通常在Expression Blend中创建,方法是右键单击JoySelector,创建新,使用绘图工具绘制椭圆,路径和组合框,并从属性窗口中选择ComboBox绑定和样式。



数据模板



在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>

其他游戏对象将使用不同的模板,然后可以使用ListBox使用WrapPanel按阅读顺序排列。 (注意在WPF中,ListBox不必在垂直列表中显示它的项目:任何面板都可以使用。)



这种技术在LOB中很重要应用程序:例如,您可以为在应用程序范围的DataTemplate中设置的发票设置默认表示,因此应用程序中提供发票列表的任何部分都将以默认格式自动显示。这可能包括图标,发票编号,带有附加信息的工具提示弹出式窗口以及允许打开和/或编辑发票的上下文菜单。



触发器和动画



在Cocoa中,您可以执行动画,但必须编写代码来创建动画和应用动画。在WPF中,您可以使用Expression Blend中的时间轴来定义动画,并在视图中设置EventTriggers和PropertyTriggers以控制其运行时间。要创建摇动按钮的动画,只需右键单击以创建时间轴,使用鼠标在时间线上的几个点设置按钮的位置,旋转或缩放,并将自动创建的EventTrigger更改为所需的事件以触​​发按钮。



Cocoa没有动画属性存储或强制机制,因此动画所做的任何更改都是永久性的:您不能删除动画,属性值还原。此外,您不能在不手动复制共享资源的情况下对共享资源的属性(例如画笔颜色)进行动画处理,并且您不能将动画设置为超出范围的值,并且控件本身强制为适当的值。在WPF中,动画系统能够分别跟踪动画值,绑定值,默认值和强制值,因此您不会遇到这些问题。



WPF您可以设置动画在按钮点击,属性状态更改(包括模型中的数据更改),模型生成的事件,连续运行或通过代码等UI事件上运行。

在WPF中,您可以创建自定义动画类,并将它们与Expression Blend结合使用,就像它们是WPF的一部分一样。您还可以绘制由内置PathAnimation使用的几何对象,而不是自己编码。



请注意,WPF有能力构建和启动动画的代码如果你真的想。还要注意,从单独的应用程序(如Quartz Composer)嵌入动画与UI对象的动画属性不同。 Cocoa和WPF都可以嵌入使用其他技术创建的动画,但是使用WPF,您可以使用Expression Blend创建一个时间轴来动画UI的任何部分。



作为绑定的一部分



Cocoa可以使用NSFormatter从单个值执行转换。任何更复杂的都必须在控制器中完成。在WPF中,您可以使用StringFormat来处理Cocoa的内置NSFormatters的简单情况,但您也可以指定一个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>这里是一个WinForms控件:< / TextBlock>
< WindowsFormsHost>
< tools:LegacyChartingControl
Width =20Height =30
Title =Graph of something
SeriesXMin =0
SeriesXMax = 10... /
< / WindowsFormsHost>
< / StackPanel>

外部创建的媒体



Cocoa和WPF都可以包含在第三方工具中创建的媒体,例如视频,动画和位图。每个环境支持底层操作系统支持的所有此类媒体类型。 WPF在控制媒体方面提供了比Cocoa更多的功能,例如,如果您将按钮的命令设置为MediaCommands.NextTrack或MediaCommands.FastForward,媒体将自动做出相应的响应。 WPF(通过Silverlight)还以完全跨平台的方式支持多个高质量的视频和音频编解码器,因此WPF在媒体的异步加载中提供了一些改进。





还有一些工具允许您将工具中创建的绘图(如Illustrator)或在Flash等工具中创建的动画转换为本地WPF图纸和动画,允许您操纵和数据绑定其属性。例如,您可以在Flash中创建一个弹跳球动画,并在顶点处数据绑定其Y坐标,以便根据您模型中的数据值让球弹起更高或更低。



垃圾收集



截至2007年,垃圾回收最终在Cocoa / Obj-C中支持,但许多库仍然无法处理它,所以大多数Cocoa代码今天写的仍然使用手动内存分配与引用计数。因此,即使今天你仍然有很多[abc版本]洒在整个Cocoa代码!



在网络浏览器中执行 $

$ WPF / NET从第一天开始垃圾收集,所以没有这个问题。 b
$ b

Cocoa应用程序目前仅限于作为桌面应用程序执行,而WPF可以在Web浏览器中使用XBAP或Silverlight技术在桌面上轻松运行。



跨平台功能



这里的故事类似:




  • Cocoa应用程序在Mac OS X上本地运行,也可以在Windows和Linux上使用Cocotron或GNUstep运行,并将自己限制为一部分功能。 p>


  • WPF应用程序在Windows上本机运行,也可以在Mac OS X和Linux上通过使用Silverlight运行,并将自己限制为一部分功能。




唯一的区别是Silverlight可以在浏览器中运行,并且比Cocotron或GNUstep有更好的供应商支持和工具。 p>

WPF的其他高级功能



到目前为止,我还没有在Cocoa这也不是在WPF / NET,但我发现很多在WPF / NET不是在Cocoa,例如:




  • 全部控件(例如按钮,文本框,组合框等)可以在2D布局内的3D场景中操作。

  • 高级绘图功能,如PolyBeziers,组合几何体,RenderTransform和LayoutTransform,Alpha透明度控件等。

  • 高级画笔,如渐变画笔,平铺图像画笔和视觉画笔,可用于创建任意复杂的画笔,例如,您可以绘制窗口的反射及其所有控件。

  • 动画子系统允许几乎所有属性都被动画化,例如我动画化一个TextBox的Text属性,使其看起来正在输入文本



第三方演算法和驱动程式



Cocoa / Obj-C可以呼叫预先编译的程式库对某些其他语言定义的对象使用C调用约定和调用调用方法。这意味着,对于需要集成到应用程序中的第三方代码,通常需要使用C风格的API。 WPF / NET可以将超过100种语言的代码直接包含到应用程序中,并允许您直接访问所有功能。此外,它还可以使用C,C ++,COM,DCOM,Web服务和其他调用约定调用使用其他语言编写的预编译代码。此外,还有开源的垫片,允许.NET Framework代码直接调用各种其他语言和系统。这意味着WPF应用程序几乎不需要包含超过少量的粘合代码来连接第三方代码,包括设备驱动程序。



语言比较



比较Objective-C和C#是一项主要任务,我不会尝试。只是说,从版本4.0,C#包含Objective-C的所有功能,许多,许多,更多。我在1989年学习了Objective-C - 很久以前C#甚至被设想 - 当时它是一个非常强大的语言。



在Objective-C中尝试这种类型的数据转换:

  DataContext = 
从AllLessons中的课程
其中lesson.Active
groupby lesson.Category into category
select new
{
categoryName = category.Key.Name,
lessonsInCategory =
从类别中的课程
select new
{
课程,
fullName = lesson.ShortName ++ lesson.Suffix,
priority = rand.Next(10)
}
};

如果AllLessons是动态提供的,您可以直接将此结果绑定到WPF(< ListBox ItemsSource ={Binding}/> )并实时动态更新。



C#你也可以做连接,排序等等。没有后端代码可以写,Visual Studio的IntelliSense帮助你完成属性的名称等等,当你编辑,甚至强调你的错误。



我不知道Objective-C和C#之间的任何好的比较,但是在维基百科上有一个很好的比较C#和Java,它调用了许多C#的功能, Objective-C。



语言绑定



Cocoa不限于Objective- C,WPF不限于C#。两者都可以从许多其他语言访问。不同的是Cocoa是围绕Objective-C构建的,所以使用它从另一种语言可以变得相当尴尬。例如,动作成为具有与Java或其他语言非常不同的语义的Objective-C方法调用。另一方面,WPF被有意设计为不需要任何特殊的C#特性,因此它可以很容易地从其他语言使用。例如,当使用Java(缺少true属性)时,PropertyDescriptor使用get和set方法。



此外,因为它是建立在.NET框架,WPF应用程序可以同时处理以多种语言编码的对象和库。这意味着,如果你发现一个伟大的C ++,Haskell或Ruby实现的算法,你可以简单地使用代码,而不需要重写它到你选择的语言。对于Cocoa,你通常必须将代码重写为Objective-C或创建shim代码来调用其他语言。



常见优点

>

以下是Cocoa与其与WPF共享的竞争对手的几个优点:




  • Rich排版功能

  • 能够添加3D图形

  • 内置丰富的文本编辑功能,包括拼写检查

  • <重做
  • 向现有类(WPj中的类别,附加的属性和样式)添加功能

  • 轻松远程调用方法调用



最终笔记



当比较Cocoa和WPF时,您应该将Interface Builder与Expression Blend进行比较,而不是与Visual Studio进行比较。 Visual Studio编写代码很好,但在我看来,Expression Blend是用于设计用户界面的工具。



对于实际应用开发,WPF和Cocoa之间的主要区别一般是不是WPF更强大的图形能力,因为这些可以通过手工编码包括在Cocoa应用程序中。主要区别是数据绑定以及从模型 - 视图 - 控制器到模型 - 视图 - 视图模型的演进,使WPF对于实际开发应用程序的效率更高。



可能错过了最近Cocoa的改进在上面的描述,因为我最近没有使用Cocoa。如果我对Cocoa(或WPF)有任何不公平,请添加评论,让我知道我错过了什么。


I have done a few months of development with Qt (built GUI programmatically only) and am now starting to work with Cocoa. I have to say, I love Cocoa. A lot of the things that seemed hard in Qt are easy with Cocoa. Obj-C seems to be far less complex than C++.

This is probably just me, so: Ho do you feel about this?

How does Cocoa compare to WPF (is that the right framework?) to Qt?
How does Obj-C compare to C# to C++?
How does XCode/Interface Builder compare to Visual Studio to Qt Creator?
How do the Documentations compare?

For example, I find Cocoa's Outlets/Actions far more useful than Qt's Signals and Slots because they actually seem to cover most GUI interactions while I had to work around Signals/Slots half the time. (Did I just use them wrong?)
Also, the standard templates of XCode give me copy/paste, undo/redo, save/open and a lot of other stuff practically for free while these were rather complex tasks in Qt.

Please only answer if you have actual knowledge of at least two of these development environments/frameworks/languages.

解决方案

I have worked with Cocoa / Obj-C on and off over the years. As of 2010 I find it quite limiting compared to WPF / NET Framework. I will list some of the differences I've found, and you can judge for yourself.

Markup language

When I design in WPF I get markup that is very simple XML that I can easily hand-edit or edit using tools I write myself. In Cocoa I must use xib files, which are not designed for easy hand-editing or manipulation. Here is a simple example of WPF markup:

<DockPanel>
  <Label>Select your favorite food:</Label>
  <ComboBox
    SelectedText="{Binding FavoriteFood}"
    SelectedItemsSource="{Binding AllFoods}" />
</DockPanel>

This is the entire markup, and is equivalent to about 50 lines of hard-to-edit .xib.

The ability to see and edit simple XAML is incredibly valuable for:

  • Direct manual editing
  • Communication with peers (eg StackOverflow)
  • Source contrrol
  • Searching
  • Automated transformations

Layout capabilities

In WPF I can use panels to automatically lay out my controls as the window size changes. I can use styles to define the spacing between my controls, or I can adjust margins to get the precise look I want, or both. In either case my UI will automatically adjust to changes in font sizes, window size, and screen resolution. In Cocoa, all controls are at specific x and y locations as with WinForms and the only thing I can do is auto-resize. This is extremely limiting. For example:

  • Controls cannot wrap around to a new row or column as the window gets smaller (WrapPanel)
  • Controls cannot add/remove detail based on available space
  • Controls cannot move around to make room for a control that has more text than was originally expected
  • Controls cannot selectively shrink or enlarge to fill available space
  • Interface Builder initially sets controls to comply with interface guidelines, but a applying new style cannot change layout.

The advantage of WPF layout is that you can express your intent via the way you add controls to panels, then adjust the precise layout later. Note that WPF can also work the old-fashioned way but once you've used panels for layout you'll never go back to X/Y layout.

For example, one application I did had rows containing star ratings plus comment boxes. Normally the row was only the height of a star rating, but when long commments were typed in the text box the TextBox got taller which made the row taller, so the following rows moved down. With WPF I got this behavior for free - with Cocoa I would have had to hand-code it.

Data connectivity

With Cocoa / Obj-C you are pretty much limited to the built-in data connectivity, which includes basic database access and serialization to and from files. With WPF / NET Framework you can directly bind your UI to practically anything under the sun, including:

  • Relational databases (SQL, Oracle, etc)
  • Object databases (Objectivity, Versant, etc)
  • Legacy databases (Access, dBase, R:Base, etc)
  • COBOL databases on mainframes
  • Proprietary database formats (hundreds)
  • Web pages
  • Web services (SOAP, REST, etc)
  • XML files
  • Flat files (comma-delmited, tab delimited, fixed width)
  • Office documents (Word, Excel, etc)
  • OpenOffice documents
  • PDF form fields
  • GPS receiver data (current location)
  • Positions of physical switches, buttons, levers, knobs, sliders, etc
  • Time (local or network)
  • Performance counters (CPU utilization, etc)
  • Cameras (Video cameras, web cams, still image cameras, etc)
  • Analog electronic inputs
  • MIDI (musical instrument keyboards, pickups, etc)
  • OBD-II (vehicle monitoring)
  • LDAP and Active Directory (user account information)
  • WBEM and SNMP (network device status and configuration)

In fact, you can bind to practically anything that has had a driver written in any NET Framework language - and there are over a hundred NET Framework languages.

Repetitive code

In Cocoa your model consists of a .h and a .m file, your controller consists of a .h and a .m file, and your view consists of a .xib file. Every single field in every object in your model must be referenced every one of these places!

In WPF / NET, a single field generally only appears in two lines of code: Once where the model is defined, and once where it is presented by the view. For example, in my code I usually define simple model fields in XML:

<Property Name="City" Type="string" />

then to create a text box to edit the city I simply drag the "City" property into my view and end up with this XAML:

<TextBox Text="{Binding City}" />

So "City" is mentioned in only two lines of code in my entire application (unless I have another "City" text box elsewhere). In Cocoa "City" will be referenced at least five times.

Binding directly to the model

In Cocoa a single controller is really only suitable for a single view: If you create a new view for the same model you need a new controller. In WPF / NET there is a better way to do it, though you can still create controllers if you really want to.

In WPF / NET a view will typically bind most of its controls directly to the model (see my City example above). Other controls will be bound to a "View Model" that models the state information associated with the current view. For example, if you are searching the "View Model" would contain the search string so it can be used by the view both to filter the results and to hilight the search text.

In WPF / NET you can also bind multiple properties of a control to the same or different parts of your model (or view model):

<TextBox Text="{Binding AmountToTransfer}"
         Background="{edf:Binding UserIsHappy ? Green : White}" />

The difference is that in WPF a view model is usually shareable between several screens that are similar in their behavior, so in a LOB application when you create a custom view all you need to do is edit a single file.

Command architecture

In Cocoa a button stores its target and action in a NSActionCell within the view, which means that it will invoke a specific method on a specific object (typically the controller). In WPF / NET a button has a Click event that works the same way, but it also has a Command property that allows you to invoke a command.

Commands in WPF are very powerful, since a single Command may be shared throughout the application. For example, WPF itself defines a Delete command. As long as your model responds to this command, adding a "Delete" button to your view is as simple as selecting the Delete command in the properties window, which creates this XAML:

<Button Command="Delete" />

This is all you have to do to get a functional delete button that deletes the object from a list. Note the built-in Delete command also:

  • Has a key binding to the Delete key on the keyboard
  • Supplies language-appropriate text ("Delete" or "Eliminar" or "Löschen" or "Supprimer" or ...)
  • Includes a descriptive tool tip

A command is routed to ancestor objects and models, so in a typical application you almost never need to specify which object receives the command.

Style sheets

In Cocoa there is no mechanism to apply style sheets to panels and have them affect all the controls in the panel, either at design time or at run time. For example an application may want to:

  • Make all the TextBoxes in a given area read-only
  • Make all labels bold
  • Give all ComboBoxes a light green background
  • Add uniform spacing between a set of buttons
  • Use a large green checkmark for a set of checkboxes
  • Add a Delete button to all lists
  • Make all Delete buttons appear as a red "brushed" X instead of as a traditional button
  • Make the same settings on several separate items

WPF / NET makes all of these operations trivial through the use of styles. You can set any property of any object through a style. Styles can be set implicitly by object type or explicitly, for example:

<Button Style="{StaticResource DeleteButtonStyle}" />

Style sheets can be defined anywhere you like: in a control libraries, at the application level, specific to a "theme", on a window, in a specific control's resource dicitionary, or directly on a control.

Control templates

In Cocoa you cannot do much to change the visual styling of controls except to subclass them, since they each draw their own appearance. In WPF / NET the appearance of a control is given by its template which can be freely replaced with pretty much anything you can think of.

For example:

  • You can use a ListBox in your drop-down menus and style it to look like regular menu items (with a checkbox beside the currently-selected item)
  • You can change a TreeView to appear as a sequence of ListBoxes instead of a tree
  • You can change a slider's "thumb" to appear as a business symbol or cartoon character depending on your target audience (slide a light bulb or Mickey Mouse back and forth)
  • You can change a slider to appear as a knob or to follow a non-linear path
  • You can change a CheckBox to appear as a click on / click off button, a lock icon that opens and closes, or a door that opens and shuts

Control templates and data templates may also include built-in animations, so for example your door can actually animate swinging open and closed when you click on it. This is trivially simple to do in Expression Blend: It takes about 20 clicks of the mouse. Just create two linear animations and attach them to event triggers.

Custom controls

Cocoa and WPF both allow you to subclass existing controls to create new ones. In Cocoa the new controls are serialized to the .xib / .nib file. In WPF they are part of the XAML just like the built-in controls:

<StackPanel>
  <TextBlock>
    Hello, <Run Text="{Binding FirstName}" />.
    <Bold>Good morning!</Bold>  How are you today?
  </TextBlock>
  <my:JoySelector Happiness="{Binding Happiness}" />
</StackPanel>

In this example JoySelector would be a control I defined and Happiness would be one of its properties.

A big difference between Cocoa and WPF is in the drawing of the custom controls. In Cocoa you must code calls to drawing primitives to create your control's appearance. While this is an option in WPF, it is usually much more easily done using a control template.

For example, in Cocoa you might write:

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;

whereas in WPF using XAML the equivalent would be:

<Ellipse Width="30" Height="20" Fill="Red" />

or in WPF in code (C#):

return new Ellipse { Width=30, Height=30, Fill=Brushes.Red };

A ControlTemplate may of course have multiple items:

<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>

This XAML would typically be created in Expression Blend by right-clicking a JoySelector, selecting Edit > Template > Create New, drawing the Ellipse, Path, and ComboBox using the drawing tools, and selecting the ComboBox binding and style from the Properties window.

Data templates

In Cocoa if you want a list or tree of items of various types, such as an equipment inventory in a game or a list of various types of accounts (investment, money market, savings), you pretty much have to code it all yourself. In WPF / NET you can use DataTemplates.

For example, if every weapon has a "hit strength" and a "defense strength" you might include a data template like this:

<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>

Other game objects would use different templates, then the inventory could be displayed using a ListBox using a WrapPanel to lay them out in reading order. (Note that in WPF, a ListBox doesn't have to present its items in a vertical list: Any panel can be used.)

This same technique is important in LOB applications: For example, you can have a default representation for an Invoice that is set in an application-wide DataTemplate, so any part of your application that presents lists of Invoices will automatically display them in the default format. This might include an icon, the invoice number, a tooltip popup with additional information, and a context menu that allows the invoice to be opened and/or edited.

Triggers and animations

In Cocoa you can do animations, but must write code both to create the animation and to apply the animation. In WPF you can define the animation using a timeline in Expression Blend, and set EventTriggers and PropertyTriggers in the view to control when it runs. To create an animation that shakes a button, just right-click to create a timeline, set the button's position, rotation or scale using the mouse at a few points on the time line, and change the automatically-created EventTrigger to the event you want to trigger the button.

Cocoa has no animation property store or coercion mechanism, so any changes made by the animation are permanent: You can't remove the animation and have the property values revert. Also you cannot animate properties of shared resources (such as brush colors) without manually copying them, and you can't animate to out-of-range values and have the control itself coerce to the appropriate value. In WPF the animation system has the ability to keep track of animation values, bound values, default values and coerced values separately so you don't run into these problems.

In WPF you can set animations to run on UI events like button clicks, property state changes (including data changes in the model), events generated by the model, to run continuously, or via code.

In WPF you can create custom animation classes and use these with Expression Blend as if they were part of WPF. You can also draw the Geometry objects used by the built-in PathAnimation rather than coding it yourself.

Note that WPF has the ability to construct and start animations in code if you really want to. Also note that embedding an animation from a separate application such as Quartz Composer, is not the same thing as animating properties of UI objects. Both Cocoa and WPF can embed animations created with other technologies but with WPF you can use Expression Blend to create a timeline that animates any part of your UI.

Conversions as part of binding

Cocoa has the ability to do conversions to and from from a single value using a NSFormatter. Anything more complicated must be done in the controller. In WPF you can use a StringFormat for the simple cases Cocoa's built-in NSFormatters cover, but you can also specify an IValueConverter or IMultiValueConverter to implement custom conversion of values. For example, you can add a custom converter to a bar chart data series to cause the data items in the bar chart to animate to their target values in rapid sequence (known as a "jelly" animation). WPF's converters can be used one-way or two-way and can convert a single value or multiple values.

Conversions also allow you to bind to multiple properties or calculations and to format the result, for example:

<TextBlock Text="{edf:Binding (Height + Width)/2, StringFormat=0.000}" />

This sort of binding with conversion is not possible in Cocoa.

Third party controls

In Cocoa you can generally only include UI widgets designed for Cocoa in your application. In WPF you can include WPF controls but you can also include sections of your UI developed using WinForms, MFC, HTML, Java, Flash, and other technologies. WPF provides facilities for integrating these other technologies directly into WPF, even to the extent of using its markup system to construct the objects and set their properties, for example:

<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>

Externally-created media

Both Cocoa and WPF can include media such as videos, animations, and bitmaps that have been created in third-party tools. Each environment supports all such media types supported by the underlying operating system. WPF provides a bit more than Cocoa in terms of controlling the media, for example you if you set a button's command to "MediaCommands.NextTrack" or "MediaCommands.FastForward", the media will automatically respond appropriately. Also, WPF provides some improvements in the asynchronous loading of media.

WPF (through Silverlight) also supports several high quality video and audio codecs in a fully cross-platform manner so you can rely on your media working on any platform.

There are also tools that allow you to convert drawings created in tools like Illustrator or animations created in tools like Flash into native WPF drawings and animations, allowing you to manipulate and data-bind their properties. For example, you could take a bouncing ball animation created in Flash and data-bind its Y coordinate at apogee so that the ball bounces higher or lower based on the data value in your model.

Garbage collection

As of 2007 garbage collection is finally supported in Cocoa / Obj-C, but many libraries still can't handle it so most of the Cocoa code being written today is still using manual memory allocation with reference counting. Thus even today you still a lot of "[abc release]" sprinkled throughout Cocoa code! WPF / NET has had garbage collection from day one, so it does not have this problem.

Execution within web browser

Cocoa applications are currently limited to executing as desktop applications, whereas WPF can run just as easily within the web browser as on the desktop, using either XBAP or Silverlight technology.

Cross-platform capability

The story here is similar:

  • Cocoa applications run natively on Mac OS X, and can also run on Windows and Linux by using Cocotron or GNUstep and restricting yourself to a subset of the features.

  • WPF applications run natively on Windows, and can also run on Mac OS X and Linux by using Silverlight and restricting yourself to a subset of the features.

The only significant difference is that Silverlight can run in the browser and has much better vendor support and tooling than Cocotron or GNUstep.

Other advanced capabilities of WPF

So far I have not found any capability in Cocoa that is not also in WPF / NET, but I have found many in WPF / NET that are not in Cocoa, for example:

  • All controls such as buttons, textboxes, comboboxes, etc can operate just as well within 3D scenes as within 2D layouts. They can also be arbitrarily stretched, rotated, skewed, etc.
  • Advanced drawing capabilities such as PolyBeziers, combined geometries, RenderTransform vs LayoutTransform, alpha transparency control, etc
  • Advanced brushes such as gradient brushes, tiled image brushes, and "Visual brushes" which allow you to create an arbitrarily complex brush for painting, for example you can paint a reflection of your window including all its controls.
  • Animation subsystem allows practically every property to be animated, for example I animated a TextBox's "Text" property to make it appear that text was being typed in

Third party algorithms and drivers

Cocoa / Obj-C can call pre-compiled libraries that use C calling conventions and call invoke methods on objects defined in certain other languages. This means that a C-style API is generally required for third-party code that needs to be integrated into your application. WPF / NET can include code written in over 100 languages directly into your application and allows you to access all functionality directly. In addition, it can also call into precompiled code written in other languages using C, C++, COM, DCOM, Web Services, and other calling conventions. In addition, there are open-source shims allowing NET Framework code to call directly into a wide variety of other languages and systems. This means that WPF applications almost never have to include more than a tiny amount of glue code to connect to third party code, including device drivers.

Language comparison

Comparing Objective-C with C# is a major task, and one I will not attempt. Suffice it to say that as of version 4.0, C# contains all the features on Objective-C and many, many, many more. I learned Objective-C in 1989 - a long time before C# was even conceived of - and at the time it was an amazingly powerful language. Now when I use it I cringe, especially at the loss of LINQ and Generics.

Try this sort of data transformation in 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)
      }
  };

If AllLessons is provided dynamically, you can directly bind this result in WPF (with <ListBox ItemsSource="{Binding}" />) and have it dynamically update in real time.

When using LINQ with C# you can also do joins, sorting, etc. There is no back-end code to write at all, and Visual Studio's IntelliSense helps you complete the names of properties, etc as you edit and even underlines your mistakes.

I don't know of any good comparison between Objective-C and C#, but there is a good comparison between C# and Java on wikipedia that calls out many of C#'s features that are also missing from Objective-C.

Language bindings

Cocoa is not restricted to Objective-C, and WPF is not restricted to C#. Both are accessible from a number of other languages. The difference is that Cocoa is built around Objective-C so that using it from another language can become quite awkward. For example, actions become an Objective-C method call which has very different semantics than Java or other languages. On the other hand, WPF was intentionally designed to not require any special C# features so it could be easily used from other languages. For example, when used with Java (which is lacking true properties), the PropertyDescriptor uses get and set methods instead.

In addition, because it is built on the NET Framework, a WPF application can simultaneously work against objects and libraries coded in multiple languages. This means that if you find a great C++, Haskell or Ruby implementation of an algorithm you can simply use the code without rewriting it into your language of choice. With Cocoa you generally have to rewrite the code as Objective-C or create shim code to call the other language.

Common advantages

Here are several advantages of Cocoa over its competitors that it shares with WPF:

  • Rich typography functionality
  • Ability to include 3D graphics
  • Built in rich text editing including spell checking
  • Undo/redo
  • Adding functionality to existing classes (categories in Obj-C, attached properties and styles in WPF)
  • Easy remoting of method calls

Final notes

When comparing Cocoa to WPF, you should compare Interface Builder with Expression Blend, not with Visual Studio. Visual Studio is fine for writing code, but in my opinion, Expression Blend is the only tool for designing the user interface.

For practical application developement, the main difference between WPF and Cocoa is generally not the more powerful graphics abilities of WPF, since these can be included in a Cocoa application by hand-coding them. The main difference is the data binding and the evolution from model-view-controller to model-view-viewmodel that makes WPF so much more efficient for actually developing applications.

I may have missed a recent Cocoa improvement in the above description since I have not used Cocoa very much recently. If I have been unfair to Cocoa (or to WPF for that matter) in any way, please add a comment and let me know what I missed.

这篇关于Cocoa与Microsoft,Qt相比怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆