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在iPhone上创建另外一个简单的应用程序,不过这次要学习下如何使用Views(视图)和View Controllers(视图控制器)来创建一个具有多个界面的应用程序。特别地,我们将使用UINavigationController来在应用...
Professional iPhone Programming with MonoTouch and .NET CSharp 英文版 英文版
压缩包仅包含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绑定,用于开发人员可以在自己的应用程序上重用的流行。如果你想获得绑定,请向问题跟踪程序添加一个新的问题 。要...
Professional iPhone Programming with MonoTouch and .NET/C#is the first book to cover MonoTouch, preparing developers to take advantage of this lucrative opportunity. This book is for .NET developers...
MonoTouch.Dialog, 使用MonoTouch简化与用户对话的工具 MonoTouch.DialogMonoTouch.Dialog 是创建对话框和显示表信息的基础,没有 Having 可以为用户界面编写数十个委托和控制器。 table 支持Pull-to-Refresh以及...
Professional iPhone® Programming with monotouch and .net/c# Wallace B. McClure Martin Bowling Craig Dunn Chris Hardy Rory Blyth 2010 This book is for .NET developers that are interested in ...
Professional iPhone Programming with MonoTouch and .NET C#
MonoTouch样本MonoTouch样品Bruki在这里
mono for iOS版的新浪微博sdk,内含weibo的sdk的binding工程、obj-c版的微博sdk、mono版的.dll文件
Packt.iOS.Development.using.MonoTouch.Cookbook.Incl.Code
iPhone高级编程——使用MonoTouch和.NETC#.rar
Professional iPhone Programming with MonoTouch and .NET_C# 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载...
MonoTouch应用开发实践指南:使用C#和.NET开发iOS应用.pdf
Apress.Developing.C#.Apps.for.iPhone.and.iPad.using.MonoTouch.iOS.Apps.Development.for.NET.Developers
[iPhone开发书籍大全].Professional.iPhone.Programming.with.MonoTouch.and.NET.CSharp(Worx.2010-6)
MTTweetieTableViewPullRefresh, iPhone上,这是obj项目的MonoTouch端口,模仿了Tweetie的Pull效果 这是 Obj-C 项目EGOTableViewPullRefresh的MonoTouch端口,模仿了Tweetie在iPhone上的刷新效果
Developing.C#.Apps.for.iPhone.and.iPad.using.MonoTouch(第1版)].源代码.zip
该模块包含针对流行的iOS或MacOS库的MonoMac和MonoTouch API绑定,开发人员可以在自己的应用程序上重用它们。 如果您想添加绑定,请向问题跟踪器添加一个新。 要构建MonoTouch绑定: To build, run `make' on the...