我了解一些 Python,对这种语言的易用性印象非常深刻。从我所见过的 Objective-C 来看,它看起来不太美观,但似乎是 Mac OS X 开发中的通用语言(这意味着它有更好的文档)。
我正在考虑开始进行 Mac 开发 - 使用 PyObjC+Python 会让我成为二等公民吗?
是的。
首先,正如您所指出的,所有文档都是针对Objective-C编写的,这是一种非常不同的语言。
一个区别是方法名称。在Objective-C中,当您向对象发送消息(Python会说“调用对象的方法”)时,方法名称(选择器)和参数会混合在一起:
NSURL *URL = /*…*/;
NSError *error = nil;
QTMovie *movie = [QTMovie movieWithURL:URL
error:&error];
这在Python中是不可能的。Python的关键字参数不算作方法名称的一部分,因此如果你这样做:
movie = QTMovie.movieWithURL(URL, error = ???)
如果你使用QTMovie类中没有名为movieWithURL
的方法,你将会得到一个异常;Objective-C示例中的消息使用了选择器movieWithURL:error:
。 movieWithURL:
和movieWithURL
是另外两个选择器。
他们无法改变这一点,因为Python的关键字参数没有顺序。假设你有一个假想的三个参数的方法:
foo = Foo.foo(fred, bar=bar, baz=baz)
现在,这会调用foo:bar:baz:
,对吧?
不要那么快。Foo也可能有一个名为foo:baz:bar:
的方法。由于Python的关键字参数没有顺序,你实际上可能会调用那个方法。同样地,如果你尝试调用foo:baz:bar:
,你实际上可能最终调用foo:bar:baz:
。事实上,这种情况不太可能发生,但如果它真的发生了,你将无法可靠地调用任何一个方法。
因此,在PyObjC中,你需要这样调用该方法:
movie = QTMovie.movieWithURL_error_(URL, ???)
你可能对 "???" 感到困惑。C语言不允许多个返回值,因此在Objective-C中,"error:"参数需要指向指针变量的指针,并且该方法将在该变量中存储一个对象(这称为按引用返回)。Python没有指针,因此桥接程序处理此类参数的方式是传递None,然后该方法将(似乎)返回一个元组。因此,正确的示例是:
movie, error = QTMovie.movieWithURL_error_(URL, None)
你可以看到,即使是一个简单的例子,它跟Objective-C文档中所展示的有所偏差。
还有其他问题,比如GIL。Cocoa应用程序将变得更加并发,而且你会想要参与其中,特别是有像NSOperation这样诱人的类存在。而GIL在多核机器上是一个严重的负担。我自己是Python开发者(不写Cocoa代码时),所以我说这个问题是冷酷的事实,无可否认。
因此,如果我要为我的应用程序切换使用别的语言,我会选择MacRuby。与PyObjC和RubyCocoa不同,对Cocoa对象的消息不需要跨语言桥梁;它是一种从底层开始的Cocoa的Ruby实现,具有用于更好地支持在其中编写Cocoa代码的语言扩展。
但那太遥远了。你只是初学者。先从Objective-C开始吧。最好保持相同语言,避免在使用的语言和文档写作所用的语言之间出现任何阻力不匹配。
此外,你会发现某些错误(例如发送给已死亡对象的消息)在没有了解Objective-C工作原理的情况下更难诊断。无论你在哪种语言中编写代码,作为新的Cocoa程序员,你都会写出这些错误。
因此,请先学习C语言,然后再学习Objective-C语言。对C和Objective-C的实用知识不应该超过几周时间,并且最终你将为其他任何事情做好更充分的准备。
我不会详细介绍我是如何学习C语言的;可以说,我不建议这种方法。我听说这本书很好,但我没有拥有或阅读过它。我有这本书,可以证实它很好,但它也不是面向Mac的;跳过关于如何编译代码的章节,改用Xcode。如果你要为Mac编写应用程序,不要试图避免学习Objective-C。PyObjC和其他语言绑定的目的是让你在应用程序中重复使用现有库,而不是让你避免学习本地工具。
这是我一直在思考的问题,虽然我希望有更多经验的人能够提供意见,但根据我的了解,Python本身不会对你造成严重限制。与Java和GCC一起,Python是编写本地跨平台应用程序的绝佳方式。一旦你掌握了它,你应该能够将Objective C的示例代码映射到你的Python代码中。
由于你可以访问所有库和事件,你可以在Python中做任何你在Objective C中能做的事情。当然,你使用的OS X专用调用和函数越多,将其移植到另一个平台就越困难,但这并不是重点。通常,图形编程和设备驱动程序是某种限制因素,但在这两种情况下,我发现有很好的支持和社区库(搜索Python和Quartz、Lightblue、libhid、PyUSB等一些示例)。
对我来说,决定性的因素是:需要什么级别的工具和IDE支持。苹果提供了一些构建新软件的优秀软件,但是像Pydev这样的工具也是编写Python代码的好地方!http://pydev.org/
所以试一试吧,我相信你不会后悔的,而且还有一个支持性强的社区可以寻求帮助和灵感。
你需要学习Objective-C:所有的教程、文档、示例代码等都是用这种语言编写的。此外,更多的人可以帮助你。
所以先学习ObjC。如果在你的第二个或第三个项目中,或者一年后,你开始一个需要Python模块的项目(比如Twisted或SQLAlchemy。但是像应用程序基础这样严重的需求,额外的提升会让一切都值得),那么你可以编写一个PyObjC应用程序,并利用你在Cocoa方面的背景获得很多语言的速度优势。
作为额外的选择,考虑使用 wxPython ,无论在 Mac 还是在 Linux 和 Windows 上都能生成一些非常好的应用程序。大部分情况下,您可以获得本地外观,但几乎不需要关注特定于平台的问题。
换句话说,PyObjC + Python 不是使用 Python 进行 Mac 开发的唯一方法。
不,你不需要了解Objective C,也不需要使用PyObjC,你也不会成为二等公民。
除非你想要做一些极其特定于MAC平台的事情,否则编写Objective C或使用PyObjC是一个非常糟糕的想法。
原因很明显,一旦你选择了objc路线,你就告别了其他平台。就这么简单。
苹果不希望你为其他平台编写代码,就像微软不希望你为其他平台编写代码一样。这就是为什么越来越多的开发人员转向开源语言,如Python、Java、Ruby等。因为你不关心苹果和微软,你只关心最有用和最容易开发的应用程序。而且,将你的应用程序仅限于MAC将使它变得不那么有用,显然使用Objective C进行开发更加困难。
Python拥有足够的库来满足您的需求,数百个库,可立即在mac平台上使用。例如,我使用pygame开发新应用程序,它不是游戏,如果我使用ObjC或PyObj完成同样的事情,我将不得不为Windows和Linux重新编写代码。而使用pygame,即使我的主要平台是macOS,我的代码在Windows和Linux中也完全相同。
这就是大多数Python库的吸引之处,它们是跨平台的。WxPython就是一个例子,有人提到它“并不完全看起来像原生界面”,难道这会阻止你将应用程序发布给Windows和Linux吗?为什么要限制自己只在MAC平台上开发?你觉得普通用户会关心应用程序的原生外观吗?即使macOS应用程序也没有原生外观,其中许多应用程序都带有自己的“眼睛糖果”图形界面。并不是说你不能使WxPython看起来100%原生,编码方式始终很重要。
当你打算开发iPhone OS时,Objective-C是有意义的选择,因为苹果认为排除Python(不仅仅是Python)是一个好主意,尽管他们被迫包括JavaScript(否则在iPhone上上网将成为噩梦)。Pyjamas也可以使Python在iPhone OS上可用(无需任何黑客或越狱手机),但具有明显的限制,因为它将Python代码转换为JavaScript,但直到苹果决定从iPhone OS中排除Python是一个真正糟糕的主意,它仍然是一个有效的解决方案。
学习Objective-C并没有什么害处。你始终可以通过pyobjc使用原生库。
但是,说实话,如果我的应用程序在使用Python库时遇到死胡同(这是非常不可能的情况),我宁愿使用Cython包装现有的跨平台C/C++库,而不是采用Objective C PyObjc方法破坏我的应用程序的跨平台能力。我最不想使用的就是任何特定于平台的东西。
现在,如果你完全不关心其他平台,那么我想Objective C可能是一个有效的选择。它看起来确实很丑陋,但我听说随着使用次数的增加,它会变得越来越好,并且有很多人喜欢它胜过C/C++。
Cocoa
,这明确是面向苹果的。 - ipmcc
AVFoundation
但它还没有准备好,因为苹果公司并没有致力于它,只有一个热心的开发者(无论多么出色)。 - dashesy