Elton's Blog

Mac

使用rvm在Mac中安装ruby和rails

by 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" ]] &amp;&amp; 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了。

3 Comments :, , more...

阻止iOS设备锁屏

by 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;
2 Comments : more...

在XCode4中添加程序调试错误信息

by on 八.07, 2011, under iPhone

当调试程序时,程序突然崩溃,默认条件下,XCode反馈的信息不够多。可以通过以下方式让XCode反馈足够多的信息。

在Edit–>Scheme里面 找到Arguments

把下面3个值设置成YES

1
2
3
NSAutoreleaseFreedObjectCheckEnabled
NSZombieEnabled
NSDebugEnabled

这种方法非常好用,建议在建立一个工程的时候,加入此设置。

6 Comments : more...

整合cocos2d API文档到XCode中

by 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文档了。

Leave a Comment :, , more...

使用Objective-C建立UUID

by 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;
}
Leave a Comment :, , more...

给iPhone添加splash页面又一法

by 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秒后,消失了。
2 Comments :, more...

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

by 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

15 Comments :, , , more...

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

by 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

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

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

4 Comments :, , , more...

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

by 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

Leave a Comment :, , , more...

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

by 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/

4 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...