Elton's Blog

Mac

在Mac OSX下安装和使用GO语言

by Elton on 2010年08月13日, under Agile Web Development, Mac

Go语言是Google新推出的结合了动态语言和静态语言优势的一个新兴的语言。下面介绍一下如何在Mac系统下安装和使用这个语言。

设置环境变量

$GOROOT
GO语言的根目录,通常是$HOME/go,当然也可以是任何其他目录。

$GOOS 和 $GOARCH
标明GO语言所在的系统和处理器类型。$GOOS可以是linux, freebsd, darwin (Mac OS X 10.5 or 10.6)和 nacl (Native Client, an incomplete port)。$GOARCH可以是amd64 (64-bit x86, the most mature port), 386 (32-bit x86), arm (32-bit ARM, an incomplete port)。

你可以在你的shell profile中设置这些变量,我是放在了~/.bash_profile里了。

  1. export GOROOT=$HOME/go
  2. export GOARCH=amd64
  3. export GOOS=darwin
  4. export PATH=$PATH:$HOME/bin

其中, $HOME/bin是GO默认的可执行文件的目录,加入到path中方便使用go的各种命令。

再执行

  1. source ~/.bash_profile

使最新的配置文件生效。

获得源文件

如果你的系统中没有安装Mercurial(没有安装它,你就无法使用hg命令),那么使用这个命令来安装它:

  1.  
  2. $ sudo easy_install mercurial
  3.  

然后使用下面的命令,还获得GO语言的源文件

  1.  
  2. $ hg clone -r release https://go.googlecode.com/hg/ $GOROOT
  3.  

安装GO语言

  1.  
  2. $ cd $GOROOT/src
  3. $ ./all.bash
  4.  

如果一切正常,你应该可以在最后看到类似的结果:

  1.  
  2. cd ../test
  3. N known bugs; 0 unexpected bugs
  4.  

撰写第一个Hello,World

  1.  
  2. $ cat >hello.go <<EOF
  3. package main
  4.  
  5. import "fmt"
  6.  
  7. func main() {
  8.         fmt.Printf("hello, world\n")
  9. }
  10. EOF
  11.  
  12. $ 6g hello.go
  13. $ 6l hello.6
  14. $ ./6.out
  15. hello, world
  16. $
  17.  

日后更新

Go是一个发展中的语言,它的版本会经常进行更新,可以使用以下命令,保持GO语言是最新版本的

  1.  
  2. $ cd $GOROOT/src
  3. $ hg pull
  4. $ hg update release
  5. $ ./all.bash
  6.  

Go的官方网站是:http://golang.org

9 Comments :, , , more...

iPhone/Mac Objective-C内存管理教程和原理剖析(四)系统自动创建新的autorelease pool

by Elton on 2010年07月29日, under Mac, iPhone

四 系统自动创建新的autorelease pool
在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的代码中加入的autorelease pool,xcode生成的代码可以被删除,但系统自动创建的新的autorelease pool是无法删除的(对于无Garbage Collection的环境来说)。Objective-C没有给出实现代码,官方文档也没有说明,但我们可以通过小程序来证明。
在这个小程序中,我们先生成了一个autorelease pool,然后生成一个autorelease的ClassA的实例,再在一个新的run loop中生成一个autorelease的ClassB的对象(注意,我们并没有手动在新run loop中生成autorelease pool)。精简的示例代码如下,详细代码请见附件中的memman-run-loop-with-pool.m。

  1.  
  2. int main(int argc, char**argv)
  3. {
  4.          NSLog(@"create an autorelasePool\n");
  5.          NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  6.  
  7.          NSLog(@"create an instance of ClassA and autorelease\n");
  8.          ClassA *obj1 = [[[ClassA alloc] init] autorelease];
  9.          NSDate *now = [[NSDate alloc] init];
  10.          NSTimer *timer = [[NSTimer alloc] initWithFireDate:now
  11.                    interval:0.0
  12.                    target:obj1
  13.                    selector:@selector(createClassB)
  14.                    userInfo:nil
  15.                    repeats:NO];
  16.          NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
  17.          [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
  18.          [timer release];
  19.          [now release];
  20.          [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例
  21.  
  22.          NSLog(@"releasing autorelasePool\n");
  23.          [pool release];
  24.          NSLog(@"autorelasePool is released\n");
  25.          return 0;
  26. }
  27.  

输出如下:

  1.  
  2. create an autorelasePool
  3. create an instance of ClassA and autorelease
  4. create an instance of ClassB and autorelease
  5. ClassB destroyed
  6. releasing autorelasePool
  7. ClassA destroyed
  8. autorelasePool is released
  9.  

注意在我们销毁autorelease pool之前,ClassB的autorelease实例就已经被销毁了。
有人可能会说,这并不能说明新的run loop自动生成了一个新的autorelease pool,说不定还只是用了老的autorelease pool,只不过后来drain了一次而已。我们可以在main函数中不生成autorelease pool。精简的示例代码如下,详细代码请见附件中的memman-run-loop-without-pool.m。

  1.  
  2. int main(int argc, char**argv)
  3. {
  4.          NSLog(@"No autorelasePool created\n");
  5.  
  6.          NSLog(@"create an instance of ClassA\n");
  7.          ClassA *obj1 = [[ClassA alloc] init];
  8.          NSDate *now = [[NSDate alloc] init];
  9.          NSTimer *timer = [[NSTimer alloc] initWithFireDate:now
  10.                    interval:0.0
  11.                    target:obj1
  12.                    selector:@selector(createClassB)
  13.                    userInfo:nil
  14.                    repeats:NO];
  15.          NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
  16.          [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
  17.          [timer release];
  18.          [now release];
  19.          [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例
  20.          NSLog(@"Manually release the instance of ClassA\n");
  21.          [obj1 release];
  22.  
  23.          return 0;
  24. }
  25.  

输出如下:

  1.  
  2. No autorelasePool created
  3. create an instance of ClassA
  4. create an instance of ClassB and autorelease
  5. ClassB destroyed
  6. Manually release the instance of ClassA
  7. ClassA destroyed
  8.  

我们可以看出来,我们并没有创建任何autorelease pool,可是ClassB的实例依然被自动销毁了,这说明新的run loop自动创建了一个autorelease pool,这个pool在新的run loop结束的时候会销毁自己(并自动release所包含的对象)。

补充说明
在研究retain count的时候,我不建议用NSString。因为在下面的语句中,

  1.  
  2. NSString *str1 = @”constant string”;
  3.  

str1的retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。
当然,如果你这样创建NSString,得到的retain count依然为1

  1.  
  2. NSString *str2 = [NSString stringWithFormat:@”123];
  3.  

摘自:http://www.cnblogs.com/VinceYuan

4 Comments :, , , more...

iPhone/Mac Objective-C内存管理教程和原理剖析(三)@property (retain)和@synthesize的默认实现

by Elton on 2010年07月29日, under Mac, iPhone

三 @property (retain)和@synthesize的默认实现
在这里解释一下@property (retain) ClassB* objB;和@synthesize objB;背后到底发生了什么(retain property的默认实现)。property实际上是getter和setter,针对有retain参数的property,背后的实现如下(请参考附件中的memman-getter-setter.m,你会发现,结果和memman-property.m一样):

  1.  
  2. @interface ClassA : NSObject
  3. {
  4.          ClassB *objB;
  5. }
  6.  
  7. -(ClassB *) getObjB;
  8. -(void) setObjB:(ClassB *) value;
  9. @end
  10.  
  11. @implementation ClassA
  12. -(ClassB*) getObjB
  13. {
  14.          return objB;
  15. }
  16.  
  17. -(void) setObjB:(ClassB*) value
  18. {
  19.          if (objB != value)
  20.          {
  21.                    [objB release];
  22.                    objB = [value retain];
  23.          }
  24. }
  25.  

在setObjB中,如果新设定的值和原值不同的话,必须要把原值对象release一次,这样才能保证retain count是正确的。
由于我们在class内部retain了一次(虽然是默认实现的),所以我们要在dealloc方法中release这个成员变量。

  1.  
  2. -(void) dealloc
  3. {
  4.          [objB release];
  5.          [super dealloc];
  6. }
  7.  

摘自:http://www.cnblogs.com/VinceYuan

Leave a Comment :, , , more...

iPhone/Mac Objective-C内存管理教程和原理剖析(二)口诀与范式

by Elton on 2010年07月29日, under Mac, iPhone

二 口诀与范式
1 口诀。
1.1 谁创建,谁释放(类似于“谁污染,谁治理”)。如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。换句话说,不是你创建的,就不用你去释放。
例如,你在一个函数中alloc生成了一个对象,且这个对象只在这个函数中被使用,那么你必须在这个函数中调用release或autorelease。如果你在一个class的某个方法中alloc一个成员对象,且没有调用autorelease,那么你需要在这个类的dealloc方法中调用release;如果调用了autorelease,那么在dealloc方法中什么都不需要做。
1.2 除了alloc、new或copy之外的方法创建的对象都被声明了autorelease。
1.3 谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。有时候你的代码中明明没有retain,可是系统会在默认实现中加入retain。不知道为什么苹果公司的文档没有强调这个非常重要的一点,请参考范式2.7和第三章。
2 范式。
范式就是模板,就是依葫芦画瓢。由于不同人有不同的理解和习惯,我总结的范式不一定适合所有人,但我能保证照着这样做不会出问题。
2.1 创建一个对象。

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init];
  3.  

2.2 创建一个autorelease的对象。

  1.  
  2. ClassA *obj1 = [[[ClassA alloc] init] autorelease];
  3.  

2.3 Release一个对象后,立即把指针清空。(顺便说一句,release一个空指针是合法的,但不会发生任何事情)

  1.  
  2. [obj1 release];
  3. obj1 = nil;
  4.  

2.4 指针赋值给另一个指针。

  1.  
  2. ClassA *obj2 = obj1;
  3. [obj2 retain];
  4. //do something
  5. [obj2 release];
  6. obj2 = nil;
  7.  

2.5 在一个函数中创建并返回对象,需要把这个对象设置为autorelease

  1.  
  2. ClassA *Func1()
  3. {
  4.   ClassA *obj = [[[ClassA alloc]init]autorelease];
  5.   return obj;
  6. }
  7.  

2.6 在子类的dealloc方法中调用基类的dealloc方法

  1.  
  2. -(void) dealloc
  3. {
  4.          …
  5.          [super dealloc];
  6. }
  7.  

2.7 在一个class中创建和使用property。
2.7.1 声明一个成员变量。

  1.  
  2. ClassB *objB;
  3.  

2.7.2 声明property,加上retain参数。

  1.  
  2. @property (retain) ClassB* objB;
  3.  

2.7.3 定义property。(property的默认实现请看第三章)

  1.  
  2. @synthesize objB;
  3.  

2.7.4 除了dealloc方法以外,始终用.操作符的方式来调用property。
self.objB 或者objA.objB
2.7.5 在dealloc方法中release这个成员变量。

  1.  
  2. [objB release];
  3.  

示例代码如下(详细代码请参考附件中的memman-property.m,你需要特别留意对象是在何时被销毁的。):

  1.  
  2. @interface ClassA : NSObject
  3. {
  4.          ClassB* objB;
  5. }
  6.  
  7. @property (retain) ClassB* objB;
  8. @end
  9.  
  10. @implementation ClassA
  11. @synthesize objB;
  12. -(void) dealloc
  13. {
  14.          [objB release];
  15.          [super dealloc];
  16. }
  17. @end
  18.  

2.7.6 给这个property赋值时,有手动release和autorelease两种方式。

  1.  
  2. void funcNoAutorelease()
  3. {
  4.          ClassB *objB1 = [[ClassB alloc]init];
  5.          ClassA *objA = [[ClassA alloc]init];
  6.          objA.objB = objB1;
  7.          [objB1 release];
  8.          [objA release];
  9. }
  10.  
  11. void funcAutorelease()
  12. {
  13.          ClassB *objB1 = [[[ClassB alloc]init] autorelease];
  14.          ClassA *objA = [[[ClassA alloc]init] autorelease];
  15.          objA.objB = objB1;
  16. }
  17.  

摘自: http://www.cnblogs.com/VinceYuan/

2 Comments :, , , more...

iPhone/Mac Objective-C内存管理教程和原理剖析(一)基本原理

by Elton on 2010年07月29日, under Mac, iPhone

前言
初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃。我在这里总结了自己对objective-C内存管理机制的研究成果和经验,写了这么一个由浅入深的教程。希望对大家有所帮助,也欢迎大家一起探讨。

此文涉及的内存管理是针对于继承于NSObject的Class。
一 基本原理
Objective-C的内存管理机制与.Net/Java那种全自动的垃圾回收机制是不同的,它本质上还是C语言中的手动管理方式,只不过稍微加了一些自动方法。
1 Objective-C的对象生成于堆之上,生成之后,需要一个指针来指向它。

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init];
  3.  

2 Objective-C的对象在使用完成之后不会自动销毁,需要执行dealloc来释放空间(销毁),否则内存泄露。

  1.  
  2. [obj1 dealloc];
  3.  

这带来了一个问题。下面代码中obj2是否需要调用dealloc?

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init];
  3. ClassA *obj2 = obj1;
  4. [obj1 hello]; //输出hello
  5. [obj1 dealloc];
  6. [obj2 hello]; //能够执行这一行和下一行吗?
  7. [obj2 dealloc];
  8.  

不能,因为obj1和obj2只是指针,它们指向同一个对象,[obj1 dealloc]已经销毁这个对象了,不能再调用[obj2 hello]和[obj2 dealloc]。obj2实际上是个无效指针。
如何避免无效指针?请看下一条。

3 Objective-C采用了引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所指向(引用)那么它的retain count为2。需要销毁对象的时候,不直接调用dealloc,而是调用release。release会让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init]; //对象生成时,retain count = 1
  3. [obj1 release]; //release使retain count减1,retain count = 0,dealloc自动被调用,对象被销毁
  4.  

我们回头看看刚刚那个无效指针的问题,把dealloc改成release解决了吗?

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1
  3. ClassA *obj2 = obj1; //retain count = 1
  4. [obj1 hello]; //输出hello
  5. [obj1 release]; //retain count = 0,对象被销毁
  6. [obj2 hello];
  7. [obj2 release];
  8.  

[obj1 release]之后,obj2依然是个无效指针。问题依然没有解决。解决方法见下一条。

4 Objective-C指针赋值时,retain count不会自动增加,需要手动retain。

  1.  
  2. ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1
  3. ClassA *obj2 = obj1; //retain count = 1
  4. [obj2 retain]; //retain count = 2
  5. [obj1 hello]; //输出hello
  6. [obj1 release]; //retain count = 2 – 1 = 1
  7. [obj2 hello]; //输出hello
  8. [obj2 release]; //retain count = 0,对象被销毁
  9.  

问题解决!注意,如果没有调用[obj2 release],这个对象的retain count始终为1,不会被销毁,内存泄露。(1-4可以参考附件中的示例程序memman-no-pool.m)
这样的确不会内存泄露,但似乎有点麻烦,有没有简单点的方法?见下一条。

5 Objective-C中引入了autorelease pool(自动释放对象池),在遵守一些规则的情况下,可以自动释放对象。(autorelease pool依然不是.Net/Java那种全自动的垃圾回收机制)
5.1 新生成的对象,只要调用autorelease就行了,无需再调用release!

  1.  
  2. ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1 但无需调用release
  3.  

5.2 对于存在指针赋值的情况,代码与前面类似。

  1.  
  2. ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1
  3. ClassA *obj2 = obj1; //retain count = 1
  4. [obj2 retain]; //retain count = 2
  5. [obj1 hello]; //输出hello
  6. //对于obj1,无需调用(实际上不能调用)release
  7. [obj2 hello]; //输出hello
  8. [obj2 release]; //retain count = 2-1 = 1
  9.  

细心的读者肯定能发现这个对象没有被销毁,何时销毁呢?谁去销毁它?(可以参考附件中的示例程序memman-with-pool.m)请看下一条。

6 autorelease pool原理剖析。(其实很简单的,一定要坚持看下去,否则还是不能理解Objective-C的内存管理机制。)
6.1 autorelease pool不是天生的,需要手动创立。只不过在新建一个iphone项目时,xcode会自动帮你写好。autorelease pool的真名是NSAutoreleasePool。

  1.  
  2. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  3.  

6.2 NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。

  1.  
  2. ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1,把此对象加入autorelease pool中
  3.  

6.3 NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,对象正式被销毁。如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,此对象依然没有被销毁,内存泄露。
6.4 默认只有一个autorelease pool,通常类似于下面这个例子。

  1.  
  2. int main (int argc, const char *argv[])
  3. {
  4. pool = [[NSAutoreleasePool alloc] init];
  5.  
  6. // do something
  7.  
  8. [pool release];
  9. return (0);
  10. } // main
  11.  

所有标记为autorelease的对象都只有在这个pool销毁时才被销毁。如果你有大量的对象标记为autorelease,这显然不能很好的利用内存,在iphone这种内存受限的程序中是很容易造成内存不足的。例如:

  1.  
  2. int main (int argc, const char *argv[])
  3. {
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5. int i, j;
  6. for (i = 0; i < 100; i++ )
  7. {
  8.  for (j = 0; j < 100000; j++ )
  9.     [NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
  10. }
  11. [pool release];
  12. return (0);
  13. } // main
  14.  

(可以参考附件中的示例程序memman-many-objs-one-pool.m,运行时通过监控工具可以发现使用的内存在急剧增加,直到pool销毁时才被释放)你需要考虑下一条。

7 Objective-C程序中可以嵌套创建多个autorelease pool。在需要大量创建局部变量的时候,可以创建内嵌的autorelease pool来及时释放内存。(感谢网友hhyytt和neogui的提醒,某些情况下,系统会自动创建autorelease pool, 请参见第四章)

  1.  
  2. int main (int argc, const char *argv[])
  3. {
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5. int i, j;
  6. for (i = 0; i < 100; i++ )
  7. {
  8.  NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
  9.  for (j = 0; j < 100000; j++ )
  10.     [NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
  11.  [loopPool release];
  12. }
  13. [pool release];
  14. return (0);
  15. } // main
  16.  

(可以参考附件中的示例程序memman-many-objs-many-pools.m,占用内存的变化极小)

转载自:http://www.cnblogs.com/VinceYuan

Leave a Comment :, , , more...

iPhone 3GS升级iOS4.0并越狱

by Elton on 2010年07月4日, under iPhone

手上有一部港行的iPhone 3GS,虽然是41周前的,但是因为之前用了Spirit,所以无法直接使用自制固件了。

今天发现一个Cydia上的软件,可以解决这个问题。

前提就是您必须在iPhone 3GS的(旧的bootrom)和Spirit 越狱3.1.3

*打开cydia,并添加源 – > http://repo.woowiz.net
*现在搜索 – > Spirit2Pwn。
*安装Spirit2Pwn和重新启动设备。

现在,Spirits越狱的机器可以接受任何自制4.0固件了.

Leave a Comment :, , , , , more...

如何使用SHA1或者MD5校验文件完整性

by Elton on 2010年07月4日, under Linux, Mac

有时候当你下载了一个大的文件,但是不知道这个文件是否完整的时候,可以使用提供下载者公布的md5或者sha1码来校验你所下载的文件是否跟下载提供着提供的文件完全一致。

如果你使用的是Mac OSX,UNIX或者Linux,可以使用以下命令来做这个工作:

  1.  
  2.  /usr/bin/openssl sha1 [full path to file]
  3.  /usr/bin/openssl md5 [full path to file]
  4.  

第一条命令是使用sha1来校验文件,第二条是使用md5来校验。 校验后会得到类似于如下的结果:

  1.  
  2.  /usr/bin/openssl md5 sample.iso
  3. MD5(sample.iso)= 3be75df53e0cfb3905af0b4f4471c9f3
  4.  

等号后面的就是对应的MD5的值,你可以跟下载提供着公布的MD5值进行比对,如果完全一致,那么恭喜你,你所下载的文件跟下载提供者的文件一模一样。

2 Comments :, , , more...

如何配置iAd

by Elton on 2010年06月29日, under iPhone

1. 导入iAd.framework
2.选择要定制iAd的TabViewController.h , 添加代码

  1.  
  2. #import <UIKit/UIKit.h>
  3. #import <iAd/ADBannerView.h>
  4. @interface TabViewController : UIViewController<ADBannerViewDelegate> {
  5.     ADBannerView *adView;
  6.     UILabel *adStatus;  
  7. }
  8. - (void)bannerViewDidLoadAd:(ADBannerView *)banner;
  9. - (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave;
  10. - (void)bannerViewActionDidFinish:(ADBannerView *)banner;
  11. - (void)bannerView:(ADBannerView *) didFailToReceiveAdWithError:(NSError *)error;
  12. - (void)adAvailabilityDidChange;
  13. @property (nonatomic, retain) ADBannerView *adView;
  14. @property (nonatomic, retain) UILabel *adStatus;
  15. @end
  16.  

3.对应的TabViewController.m

  1.  
  2. #import "TabViewController.h"
  3. @implementation TabViewController
  4. @synthesize adStatus;
  5. @synthesize adView;
  6. // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
  7. - (void)viewDidLoad {
  8.     [super viewDidLoad];
  9.    
  10.     adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 250, 320, 50)];
  11.     self.adView.delegate = self;
  12.     self.adView.backgroundColor = [UIColor whiteColor];
  13.     [self.view addSubview:adView];
  14.    
  15.     adStatus = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 200, 30)];
  16.     [self.view addSubview:adStatus];
  17.    
  18.     NSLog(@"Trying to change the ad status");
  19. }
  20. - (void)adAvailabilityDidChange {
  21.     NSLog(@"[iAd]: Ads are available! Let’s display one!");
  22.    
  23.     //    if([ADManager sharedAdManager].canPresentModalAd == YES)
  24.     //        [[ADManager sharedAdManager] presentModalAdFromViewController:self];
  25. }
  26. - (void)cancelBannerViewAction {
  27.     NSLog(@"Banner was cancelled!");
  28.    
  29.     self.adStatus.text = @"[iAd]: Bannes was closed.";
  30. }
  31. - (void)bannerViewDidLoadAd:(ADBannerView *)banner {
  32.     NSLog(@"[iAd]: Ad did load.");
  33.     self.adStatus.text = @"[iAd]: Ad did load.";
  34. }
  35. - (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave {
  36.     NSLog(@"[iAd]: An action was started from the banner. Application will quit: %d", willLeave);
  37.    
  38.     self.adStatus.text = @"[iAd]: An action was started from the banner. Application will quit: %d", willLeave;
  39.    
  40.     return YES;
  41. }
  42. - (void)bannerViewActionDidFinish:(ADBannerView *)banner {
  43.     NSLog(@"[iAd]: Action finished.");
  44.    
  45.     self.adStatus.text = @"[iAd]: Action finished.";
  46. }
  47. - (void)bannerView:(ADBannerView *) didFailToReceiveAdWithError:(NSError *)error {
  48.     NSLog(@"[iAd]: Faild to load the banner: %@", error);
  49.    
  50.     self.adStatus.text = @"[iAd]: Faild to load the banner: %@", error;
  51. }
  52. - (void)didReceiveMemoryWarning {
  53.     // Releases the view if it doesn’t have a superview.
  54.     [super didReceiveMemoryWarning];
  55.    
  56.     // Release any cached data, images, etc that aren’t in use.
  57. }
  58. - (void)viewDidUnload {
  59.     // Release any retained subviews of the main view.
  60.     // e.g. self.myOutlet = nil;
  61. }
  62. - (void)dealloc {
  63.     [super dealloc];
  64. }
  65. @end
  66.  
7 Comments :, , more...

理解iPhone项目的BaseSDK和DeploymentTarget含义

by Elton on 2010年06月17日, under iPhone

iPhone OS的版本众多,很多用户由于各种各样的原因没有升级到最新版,这就给我们开发者带了麻烦。作为开发者,我们都希望软件的受众越多越好。怎么样让软件尽量适应最多的iPhone OS?这里我们就应该了解iPhone项目的Base SDK和iPhone OS Deployment Target。

Base SDK指的是当前编译用的SDK版本。iPhone OS Deployment Target指的是编译出的程序将在哪个系统版本上运行。

用更简单实用的语句描述如下:

Base SDK设置为当前xcode所支持的最高的sdk版本,比如”iphone Device 4.0″。iPhone OS Deployment Target设置为你所支持的最低的iPhone OS版本,比如”iPhone OS 3.0″。

这样设置之后,你的程序就可以运行于从iPhone OS 3.0 到 4.0的设备之上。当然,前提是,你没有用到4.0新加的API。

那么如果需要使用到新的API怎么办呢?请参考官方Sample MailComposer http://developer.apple.com/iphone/library/samplecode/MailComposer/index.html

转载自http://www.cnblogs.com/vinceoniphone/archive/2010/06/13/1757743.html

1 Comment :, more...

将你的Snow Leopard设置为64位

by Elton on 2010年03月30日, under Mac

很多人对Snow Leopard的64位还是一头雾水,下面我详细说一下。

首先,默认情况下,Snow Leopard总是开启32位内核;如果你的CPU是Core 2或者Core i7(的话,系统会在运行程序时自动启动Universal Binary中的64位部分(这里的Universal是32位Intel和64位Intel的Universal,不是指PPC和Intel的),因为默认的32位内核可以运行64位程序。但是,如果你想从内核就变成完全的64位,那么需要你的Mac还具备一个条件,就是你的EFI必须是64位的。EFI是固件用户接口,这里指的是你的固件必须是64位的。

EFI是否为64位的判别方法是:
打开终端,输入代码:

  1.  
  2. ioreg -l -p IODeviceTree | grep "firmware-abi" | sed -e ‘s/[^0-9A-Z]//g’
  3.  

回车后,如果返回EFI64,则表示是64位的EFI,如果是EFI32则表明是32位的EFI……

通过Mactracker搜索,得到的分界如下:
MacBook:由于苹果限制,MB均不可开启64位内核。
MacBook Pro:MA895/896/897(Mid 2007)及以前的机型是32位的EFI,之后的机型是64位。
iMac:MA876/877/878(Mid 2007)有一部分是32位的EFI,一部分是64位的EFI,在这之前的都是32位,之后都是64位。
Mac Pro:第一代4核和8核都是32位,以后的都是64位。
注意,以上统计信息不一定准确,如果你在自己的机器上发现与上述写法不符的,请及时提出,我将做出更正!
目前已知MA895(预装Tiger)也具备64位EFI,因此wikipedia所谓预装Tiger是32位EFI的言论已经不靠谱了……

关于开启64位内核后的检查方法有四种:
1、进入“About This Mac”,点击“More Info”,在弹出的“System Profiler”中选择左边的“Software”,在右侧可以看到“64-bit kernel and extensions”,即可得知是否开启了64位内核。

2、打开终端,输入“uname -m”即可查看内核构架:

3、打开终端,输入”uname -v”即可查看内核发布信息:

4、打开“活动监视器”,找到进程“kernel_tasks”(PID为0),查看它的构架,它就代表内核。

最后说明开启64位的方法:
暂时性方法:
开机启动听到“咚”的一声马上按住“6″和”4″直到启动完成。建议先用这种方法查看开启64位内核是否有问题,我曾经在一台机器上面尝试开启64位后键盘失灵了。
永久性方法:
打开终端,拷贝下面的命令,回车运行:

  1.  
  2. sudo /Applications/TextEdit.app/Contents/MacOS/TextEdit /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
  3.  

在弹出的文本编辑器中,找到kernel_flag下面的,并把它改写成arch=x86_64.
也就是说,改好的文件应该是这个样子:

  1.  
  2.         <?xml version="1.0" encoding="UTF-8"?>
  3.         <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  4.         <plist version="1.0">
  5.                 <dict>
  6.                         <key>Kernel</key>
  7.                         <string>mach_kernel</string>
  8.                         <key>Kernel Flags</key>
  9.                         <string>arch=x86_64</string>
  10.                 </dict>
  11.         </plist>
  12.  

改完之后保存退出就可以了。

5 Comments :, , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit my friends!

A few highly recommended friends...