Mac
使用rvm在Mac中安装ruby和rails
by Elton on 九.09, 2011, under Mac, Rails
MacOS默认安装的是ruby 1.8.7,如果你想使用ruby 1.9.2的话,除了在官网下载源码编译安装外,可以使用rvm来协助安装。
STEP-1 安装RVM
在Terminal中输入以下命令即可安装
1 | bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) |
为了可以在shell中使用,需要在.bash_profile中输入以下命令
1 2 3 4 5 | cd ~/ sudo vim .bash_profile #在.bash_profile中加入 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session. |
之后退出Terminal,重启它。
STEP-2 安装Ruby
使用以下命令,可以看到rvm可以支持安装的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ rvm list known # MRI Rubies 1.8.6[-p420] 1.8.6-head 1.8.7[-p352] 1.8.7-head 1.9.1-p378 1.9.1[-p431] 1.9.1-head 1.9.2-p180 1.9.2[-p290] 1.9.2-head ruby-head ... |
使用下面的命令安装ruby 1.9.2
1 | rvm install 1.9.2 |
然后使用下面命令,让系统使用新的ruby
1 2 3 4 | $rvm use 1.9.2 Using /Users/elton/.rvm/gems/ruby-1.9.2-p290 $ruby -v ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0] |
当你重启机器后,你会发现又回复成了1.8.7了,可以使用下面命令,让系统默认使用1.9.2
1 | rvm --default use 1.9.2 |
STEP-3 安装Rails
这步很简单
1 | gem install rails |
之后就可以使用最新的ruby和rails了。
阻止iOS设备锁屏
by Elton on 八.22, 2011, under iPhone
默认,所有iOS设备在过了设定的休眠时间后,都会自动锁屏。 如果你的应用不希望iOS设备自动锁屏,可以使用以下方式来保持屏幕一直开着。
1 2 3 4 5 | // Disable the idle timer [[UIApplication sharedApplication] setIdleTimerDisabled: YES]; // Or for those who prefer dot syntax: [UIApplication sharedApplication].idleTimerDisabled = YES; |
在XCode4中添加程序调试错误信息
by Elton on 八.07, 2011, under iPhone
当调试程序时,程序突然崩溃,默认条件下,XCode反馈的信息不够多。可以通过以下方式让XCode反馈足够多的信息。
把下面3个值设置成YES
1 2 3 | NSAutoreleaseFreedObjectCheckEnabled NSZombieEnabled NSDebugEnabled |
这种方法非常好用,建议在建立一个工程的时候,加入此设置。
整合cocos2d API文档到XCode中
by Elton on 十二.12, 2010, under iPhone, Mac
cocos2d是经常使用的iOS游戏引擎,在编写代码的时候,经常需要参考它的API文档,本文主要介绍如何将cocos2d的文档整合到XCode中。
安装doxygen
从这里下载 http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc DMG安装包。
然后点击安装即可。
安装Graphviz
从这里下载http://www.ryandesign.com/graphviz/
然后点击安装。安装文件会安装到/usr/local/graphviz-x.y/bin目录中。
设置doxygen
修改doxygen.config文件,将HAVE_DOT设置成YES,将DOT_PATH设置成/usr/local/graphviz-x.y/bin
选择cocos2d-documentation target
- 打开 cocos2d-iphone的xcode项目工程
- 选择 “cocos2d-documentation” target
- XCode -> Project -> Set Active Target -> cocos2d-documentation

生成项目
- 像生成其他项目一样生成此项目
- XCode -> Build -> Build

之后就可以在文档中查看cocos2d文档了。
使用Objective-C建立UUID
by Elton on 十一.29, 2010, under Mac
UUID是128位的值,它可以保证唯一性。通常,它是由机器本身网卡的MAC地址和当前系统时间来生成的。
UUID是由中划线连接而成的字符串。例如:13222F23-C76A-7781-0C12-0293E3B34398.
下面这个方法可以生成UUID并以字符串的方式进行返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | - (NSString *)createUUID { // Create universally unique identifier (object) CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault); // Get the string representation of CFUUID object. NSString *uuidStr = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuidObject); // If needed, here is how to get a representation in bytes, returned as a structure // typedef struct { // UInt8 byte0; // UInt8 byte1; // ... // UInt8 byte15; // } CFUUIDBytes; CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuidObject); CFRelease(uuidObject); return uuidStr; } |
给iPhone添加splash页面又一法
by Elton on 十.25, 2010, under iPhone
之前有发过一篇文章,介绍了如何添加splash页面。
现在发现有一个更简单的方法。
1. 将你需要的splash界面的图片,存成Default.png
2. 在XXXAppDelegate.m程序中,插入如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //--insert a delay of 5 seconds before the splash screen disappears-- [NSThread sleepForTimeInterval:5.0]; // Override point for customization after application launch. // Add the view controller’s view to the window and display. [window addSubview:viewController.view]; [window makeKeyAndVisible]; return YES; } 这样splash页面就停留5秒后,消失了。 |
在Mac OSX下安装和使用GO语言
by Elton on 八.13, 2010, 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 2 3 4 | export GOROOT=$HOME/go export GOARCH=amd64 export GOOS=darwin export PATH=$PATH:$GOROOT/bin |
其中, $GOROOT/bin是GO默认的可执行文件的目录,加入到path中方便使用go的各种命令。
再执行
1 | source ~/.bash_profile |
使最新的配置文件生效。
获得源文件
如果你的系统中没有安装Mercurial(没有安装它,你就无法使用hg命令),那么使用这个命令来安装它:
1 | $ sudo easy_install mercurial |
然后使用下面的命令,还获得GO语言的源文件
1 | $ hg clone -r release https://go.googlecode.com/hg/ $GOROOT |
安装GO语言
1 2 | $ cd $GOROOT/src $ ./all.bash |
如果一切正常,你应该可以在最后看到类似的结果:
1 2 | --- cd ../test N known bugs; 0 unexpected bugs |
撰写第一个Hello,World
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ cat >hello.go <<EOF package main import "fmt" func main() { fmt.Printf("hello, worldn") } EOF $ 6g hello.go $ 6l hello.6 $ ./6.out hello, world $ |
日后更新
Go是一个发展中的语言,它的版本会经常进行更新,可以使用以下命令,保持GO语言是最新版本的
1 2 3 4 | $ cd $GOROOT/src $ hg pull $ hg update release $ ./all.bash |
Go的官方网站是:http://golang.org
iPhone/Mac Objective-C内存管理教程和原理剖析(四)系统自动创建新的autorelease pool
by Elton on 七.29, 2010, under iPhone, Mac
四 系统自动创建新的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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | int main(int argc, char**argv) { NSLog(@"create an autorelasePooln"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"create an instance of ClassA and autoreleasen"); ClassA *obj1 = [[[ClassA alloc] init] autorelease]; NSDate *now = [[NSDate alloc] init]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:now interval:0.0 target:obj1 selector:@selector(createClassB) userInfo:nil repeats:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; [timer release]; [now release]; [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例 NSLog(@"releasing autorelasePooln"); [pool release]; NSLog(@"autorelasePool is releasedn"); return 0; } |
输出如下:
1 2 3 4 5 6 7 | create an autorelasePool create an instance of ClassA and autorelease create an instance of ClassB and autorelease ClassB destroyed releasing autorelasePool ClassA destroyed autorelasePool is released |
注意在我们销毁autorelease pool之前,ClassB的autorelease实例就已经被销毁了。
有人可能会说,这并不能说明新的run loop自动生成了一个新的autorelease pool,说不定还只是用了老的autorelease pool,只不过后来drain了一次而已。我们可以在main函数中不生成autorelease pool。精简的示例代码如下,详细代码请见附件中的memman-run-loop-without-pool.m。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int main(int argc, char**argv) { NSLog(@"No autorelasePool createdn"); NSLog(@"create an instance of ClassAn"); ClassA *obj1 = [[ClassA alloc] init]; NSDate *now = [[NSDate alloc] init]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:now interval:0.0 target:obj1 selector:@selector(createClassB) userInfo:nil repeats:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; [timer release]; [now release]; [runLoop run]; //在新loop中调用一函数,生成ClassB的autorelease实例 NSLog(@"Manually release the instance of ClassAn"); [obj1 release]; return 0; } |
输出如下:
1 2 3 4 5 6 | No autorelasePool created create an instance of ClassA create an instance of ClassB and autorelease ClassB destroyed Manually release the instance of ClassA ClassA destroyed |
我们可以看出来,我们并没有创建任何autorelease pool,可是ClassB的实例依然被自动销毁了,这说明新的run loop自动创建了一个autorelease pool,这个pool在新的run loop结束的时候会销毁自己(并自动release所包含的对象)。
补充说明
在研究retain count的时候,我不建议用NSString。因为在下面的语句中,
1 | NSString *str1 = @”constant string”; |
str1的retain count是个很大的数字。Objective-C对常量字符串做了特殊处理。
当然,如果你这样创建NSString,得到的retain count依然为1
摘自:http://www.cnblogs.com/VinceYuan
iPhone/Mac Objective-C内存管理教程和原理剖析(三)@property (retain)和@synthesize的默认实现
by Elton on 七.29, 2010, under iPhone, Mac
三 @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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | @interface ClassA : NSObject { ClassB *objB; } -(ClassB *) getObjB; -(void) setObjB:(ClassB *) value; @end @implementation ClassA -(ClassB*) getObjB { return objB; } -(void) setObjB:(ClassB*) value { if (objB != value) { [objB release]; objB = [value retain]; } } |
在setObjB中,如果新设定的值和原值不同的话,必须要把原值对象release一次,这样才能保证retain count是正确的。
由于我们在class内部retain了一次(虽然是默认实现的),所以我们要在dealloc方法中release这个成员变量。
1 2 3 4 5 | -(void) dealloc { [objB release]; [super dealloc]; } |
摘自:http://www.cnblogs.com/VinceYuan
iPhone/Mac Objective-C内存管理教程和原理剖析(二)口诀与范式
by Elton on 七.29, 2010, under iPhone, Mac
二 口诀与范式
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 | ClassA *obj1 = [[ClassA alloc] init]; |
2.2 创建一个autorelease的对象。
1 | ClassA *obj1 = [[[ClassA alloc] init] autorelease]; |
2.3 Release一个对象后,立即把指针清空。(顺便说一句,release一个空指针是合法的,但不会发生任何事情)
1 2 | [obj1 release]; obj1 = nil; |
2.4 指针赋值给另一个指针。
1 2 3 4 5 | ClassA *obj2 = obj1; [obj2 retain]; //do something [obj2 release]; obj2 = nil; |
2.5 在一个函数中创建并返回对象,需要把这个对象设置为autorelease
1 2 3 4 5 | ClassA *Func1() { ClassA *obj = [[[ClassA alloc]init]autorelease]; return obj; } |
2.6 在子类的dealloc方法中调用基类的dealloc方法
1 2 3 4 5 | -(void) dealloc { … [super dealloc]; } |
2.7 在一个class中创建和使用property。
2.7.1 声明一个成员变量。
1 | ClassB *objB; |
2.7.2 声明property,加上retain参数。
1 | @property (retain) ClassB* objB; |
2.7.3 定义property。(property的默认实现请看第三章)
1 | @synthesize objB; |
2.7.4 除了dealloc方法以外,始终用.操作符的方式来调用property。
self.objB 或者objA.objB
2.7.5 在dealloc方法中release这个成员变量。
1 | [objB release]; |
示例代码如下(详细代码请参考附件中的memman-property.m,你需要特别留意对象是在何时被销毁的。):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @interface ClassA : NSObject { ClassB* objB; } @property (retain) ClassB* objB; @end @implementation ClassA @synthesize objB; -(void) dealloc { [objB release]; [super dealloc]; } @end |
2.7.6 给这个property赋值时,有手动release和autorelease两种方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void funcNoAutorelease() { ClassB *objB1 = [[ClassB alloc]init]; ClassA *objA = [[ClassA alloc]init]; objA.objB = objB1; [objB1 release]; [objA release]; } void funcAutorelease() { ClassB *objB1 = [[[ClassB alloc]init] autorelease]; ClassA *objA = [[[ClassA alloc]init] autorelease]; objA.objB = objB1; } |
摘自: http://www.cnblogs.com/VinceYuan/



