MonoTouch使用静态编译方式将代码编译为ARM二进制代码。使用MonoTouch创建的每一个应用程序都是独立的,也就是说,应用程序所需要的东西都要打包,之所以这样,是因为iPhone不允许使用共享库。MonoTouch通过绑定方式向C#公开iPhone的原生库,因而不需要在语言之间做转换。通过静态编译(Ahead-Of-Time,AOT)生成ARM二进制代码,MonoTouch应用程序就可满足发布应用程序到App Store的所有必需条件。
注意 在写本书(《MonoTouch应用开发实践指南:使用C#和.NET开发iOS应用》)的时候,许多使用MonoTouch开发的应用程序已经发布到App Store。在网站monotouch.info里有这些应用程序的完整列表,并有大量相关资源的链接。现在还可以在http://monotouch.net/Apps查看应用程序的展示。
然而,由于苹果政策和内核的限制,JIT编译的代码是不允许的。这就限制了.NET的某些领域(如CodeDOM、Reflection-Emit(尽管映射可以使用)、虚拟泛型方法、非确定性泛型和动态语言运行库(Dynamic Language Runtime,DLR))的使用。在一般情况下,大多数非UI的C#代码都可以稍做修改或不做修改就能移植到MonoTouch中。
对于刚才在MonoTouch中创建的应用程序,现在来看看它们在MonoDevelop中生成时都做了什么事情(例如在虚拟器生成一个发布版本)。
设置配置为Release | iPhoneSimulator,然后生成解决方案。生成后,在Finder中浏览工程目录。
提示 在MonoDevelop解决方案树中右击该工程,并选择Open Containing Folder就可在Finder中打开工程目录。
在Finder的工程目录依次打开以下目录:bin→iPhoneSimulator→Release。在目录中,可以看到生成的应用程序包。如果生成的是debug(调试)版本,就可在Debug目录中找到它,它在iPhone目录中而不是iPhoneSimulator目录中。在所有情况下,目标目录结构就是编译应用时生成应用程序包的形式。有一个扩展名为.app的特殊文件夹,它的作用是使应用程序看起来像单一的文件,便于部署。对于当前的应用程序,会看到文件的名字为LMT2-2.app。如果在Finder中右击该文件并选择Show
Package Contents,将看到如下图所示的编译后的执行文件和应用程序所依赖的文件。
应用程序包的内容
各种DLL文件和EXE文件是剩余的元数据。此外,两个图片文件用前面的Build Action of Content,以及info.plist文件和MainWindow.nib标记。文件info.plist是一个属性列表文件,它是XML文件,包含了应用程序不同元数据构成的字典。文件MainWindow.nib是MainWindow.xib文件的二进制版本。
注意 在部署应用程序到App Store的时候,需要将.app文件压缩为zip文件和一些图片文件一起上传。
在应用程序包中,最重要的文件是LMT2-2,这是由AOT编译的,包含项目中所有的依赖项,包含MonoTouch提供的用于应用程序内管理内存的工具,是可在Unix上执行的文件。MonoTouch的内存管理与iPhone上的Objective-C不同,它是Mono垃圾收集器的一个分支版本,负责应用程序代码中所有的内存管理工作。
注意 MAC OS X中的Objective-C 2.0并没有垃圾收集器。此外,在模拟器上,MonoTouch使用JIT编译而不是AOT。
回头看看Objective-C版本的应用程序,会注意到dealloc方法会发送一个释放信息给imageView;而在MonoTouch版本中,则不需要。其原因就是因为MonoTouch有垃圾收集器,而在iPhone的Objective-C中没有。它依赖于基于引用计数(retain count)的内存管理模型。如果熟悉的话,会发现这有点儿类似于COM,至少表面上是这样。但是,UIImageView并不是一个.NET的类,怎样才能收集它呢?下面将讲述这问题。
内存管理
要了解MonoTouch如何使用原生类管理内存,首先要了解Objective-C管理内存的知识。在Objective-C中,内存管理是通过引用计数来实现的。每当创建对象时,就会向Objective-C发送一个alloc信息,然后返回对象(实际上是对象的指针,这里把引用作为对象)和它的引用计数。每发送一个引用信息给对象,对象的引用计数就会加1;而每当一个释放信息发送给对象,引用计数就会减1,当对象的引用计数为0时,内存就会释放。
注意 Objective-C的alloc和init版本的组合类似于C#中的构造函数。
此外,在许多情况下,工厂方法(factory method)模式的类只返回一个对象。在这种情况下,如果分配内存后,工厂方法在内部释放对象,那么在调用者有机会使用它之前,该对象将销毁,这时,如果工厂方法对这视而不见,并返回了该分配对象(包含引用计数),那么该对象将永远不会销毁。通过由NSAutoreleasePool类实现的自动释放池(autorelease pool),可以解决这个问题。基本上,NSAutoreleasePool会延迟对象的销毁,这样调用者就能在它销毁前使用它。在iPhone的引用计数世界中,对象会添加到自动释放池直到释放池自身发出一个遗漏(drain)信息(或释放信息)时,才会发送释放信息。只要释放池中的对象不明确地发送一个保留信息,对象就会销毁。
当任何带有引用计数为1的对象释放时,就会调用dealloc方法,这时就可以调用对象的释放方法来清理对象(即释放对象的指针)。
基于以上信息,现在探讨MonoTouch如何与原生代码交互。对于Objective-C对象,MonoTouch在主线程创建一个自动释放池和线程池线程。因此,每当线程使用Objective-C类时,MonoTouch开发人员就要创建一次自动释放池,例如,使用以下代码创建线程:
void DoSomethingOnAnotherThread ()
{
Thread t = new Thread (DoSomething);
t.Start ();
}
在“DoSomething”方法内要使用Objective-C对象(也就是说,从NSObject派生的任何类),都需要将代码包含在自动释放池内,如以下代码:
void DoSomething()
{
using(var pool = new NSAutoreleasePool())
{
//code that touched Objective-C objects ...
}
}
提示 如果在运行时出现“autoreleased with no pool in place—just leaking,”这样的警告,如之前所示那样将代码包含到NSAutoreleasePool中即可。
除此之外,我们发现MonoTouch在内存管理方面做得相当出色。当然,.NET对象会通过MonoTouch GC自身进行管理。需要内存管理的其他地方,可能还需要采取更精细的内存控制,或者至少清楚NSObject基类的IDisposable实现。在MonoTouch端,会发送释放信息到NSObject对象子类的实例(附带一些内部数据结构的清理),如果要销毁的是占用大量内存的对象,这非常有用,而且宜早不宜迟。对于NSAutoreleasePool,当释放信息发送到释放池时,会将释放信息发送到它内部所有的自动释放对象。
-----------------------------
本文节选自《MonoTouch应用开发实践指南:使用C#和.NET开发iOS应用》第2.3节“MonoTouch的工作原理”
原书名:Learning MonoTouch: A Hands-On Guide to Building iOS Applications with C# and .NET
作者:(美)Michael Bluestein 著
译者:黄灯桥 黄浩宇 译
本书系统讲解了利用MonoTouch开发iOS应用的技术和方法,并包含大量精心设计的案例,可操作性极强。它是有效指导有经验的.NET开发者利用已掌握的.NET技术快速开发iOS应用的参考书,为.NET开发者低成本地向iOS开发者过渡提供了捷径。
阅读本书PDF样章,请访问:http://vdisk.weibo.com/s/j8IFO
豆瓣收藏本书,请访问:http://book.douban.com/subject/20394299/
分享到:
相关推荐
【MonoTouch中的MVC简介】 在MonoTouch框架中开发针对iPhone的应用程序时,理解MVC(Model-View-Controller)模式至关重要。MVC是一种软件设计模式,它将应用程序的业务逻辑、用户界面和数据管理分离开来,以提高可...
虽然我们主要关注的是MonoTouch版本,但了解其内部工作原理也是有益的。 3. **.dll文件**:这是编译好的 MonoTouch 版微博SDK的动态链接库,用于在Xamarin.iOS项目中引用和使用。 使用这个SDK时,开发者需要按照...
压缩包仅包含Mac版本的破解文件,也仅适用于...monotouch-8.2.0.193.pkg mono-android-4.18.0-34.pkg MonoFramework-MDK-3.10.0.19.macos10.xamarin.x86.pkg 此版本可以使用Windows低版本的Xamarin.iOS进行远程调试.
monotouch-bindings, MonoTouch的第三方绑定集合 monotouch绑定这个模块包含MonoMac和 macOS的API绑定,用于开发人员可以在自己的应用程序上重用的流行。如果你想获得绑定,请向问题跟踪程序添加一个新的问题 。要...
MonoTouch.Dialog, 使用MonoTouch简化与用户对话的工具 MonoTouch.DialogMonoTouch.Dialog 是创建对话框和显示表信息的基础,没有 Having 可以为用户界面编写数十个委托和控制器。 table 支持Pull-to-Refresh以及...
- **工作原理**:它通过编译C#代码为本地ARM架构的机器码,确保应用程序在iPhone上运行时具有接近原生应用的性能。 - **优势**:包括但不限于代码重用、统一的开发环境、丰富的类库支持以及与.NET生态系统的无缝集成...
《Packt.iOS.Development.using.MonoTouch.Cookbook.Incl.Code》这本书是针对iOS应用开发的一本实用指南,特别关注使用MonoTouch框架进行开发。MonoTouch是Mono项目的一部分,它为开发者提供了一种使用C#、.NET ...
《iPhone高级编程——使用MonoTouch和.NET C#》是一本深度探讨如何利用MonoTouch框架和.NET C#语言进行iOS应用开发的专业教程。MonoTouch是Xamarin公司的产品,它允许开发者使用C#、VB.NET或F#来构建原生的iOS应用,...
《Developing C# Apps for iPhone and iPad using MonoTouch》是一本深入探讨如何使用MonoTouch框架构建iOS应用的书籍。MonoTouch是Xamarin公司推出的一款工具,它允许开发人员使用C#语言和.NET Framework来开发原生...
此外,还将介绍MonoTouch的基本概念、工作流程和工具链。 3. **首个项目:创建简单的iOS应用**:第二章通过一个简单的例子介绍了如何创建第一个iOS应用,让读者快速上手,并熟悉基本的应用构建过程。 4. **多屏幕...
- **定义**: MonoTouch 是一个开源项目,它允许.NET 和 C# 开发者使用他们熟悉的语言来开发原生的 iPhone 应用程序。 - **目的**: 为.NET 和 C# 开发者提供了一个无需学习 Objective-C 或其他 Apple 编程语言即可...
MonoTouch是针对iOS平台的开发工具,它允许开发者使用C#语言和.NET框架来构建原生的iOS应用程序。MonoTouch是Xamarin的一部分,Xamarin现在已经被Microsoft收购,并整合到Visual Studio for Mac和Visual Studio中,...
本书《***/C#》是一本关于使用MonoTouch和.NET C#进行iPhone开发的实用指南,作者为Wallace B. McClure, Martin Bowling, Craig Dunn, Chris Hardy, 和 Rory Blyth。该书由Wiley Publishing, Inc.在2010年出版,并且...
MonoTouch应用开发实践指南:使用C#和.NET开发iOS应用.pdf
MTTweetieTableViewPullRefresh, iPhone上,这是obj项目的MonoTouch端口,模仿了Tweetie的Pull效果 这是 Obj-C 项目EGOTableViewPullRefresh的MonoTouch端口,模仿了Tweetie在iPhone上的刷新效果
该模块包含针对流行的iOS或MacOS库的MonoMac和MonoTouch API绑定,开发人员可以在自己的应用程序上重用它们。 如果您想添加绑定,请向问题跟踪器添加一个新。 要构建MonoTouch绑定: To build, run `make' on the...
本章将介绍MonoTouch如何将iOSSDK抽象化,从而可以使用C#的原生类进行开发,还介绍如何使用outlet,并将CocoaTouchDelegate模型和C#的事件模型进行比较,讲解如何在C#中使用这两种模式。本章还将介绍Objective-C的...