2011-11-24

git 使用筆記

刪除所有 .git 資料夾
    find . -type f | grep -i .git | xargs rm
取得程式:
    git clone git://URL
取得最新的程式:
    git pull
目前狀態:
    git status
如果確定 repo 有更新,但使用 git pull 確沒有效果(顯示 Your system reports no Git commands at all.)時使用:
    git fetch origin master:tmp
    git merge tmp

程式修改完之後:
    git add . 
    git commit –a –m '註解'

    git commit -i <file> -m '註解'
刪除沒有被加入到 git 的檔案:
    git clean –d -f
回復上次 commit 前的狀態(包含實際檔案):
    git reset –-hard HEAD^
回復到與 repo 上 origin/master 相同的狀態(包含實際檔案):
    git reset –-hard origin/master
個別檔案回復到 modified 之前的狀態(包含實際檔案):
    git checkout <filename>
個別檔案回復到某次 commit 時的狀態(包含實際檔案):
    git checkout <commit id> <filename>
回復上次 commit 前的狀態(不包含實際檔案):
    git reset –-soft HEAD^
更改 branch 名稱:
    git branch -m <old_name> <new_name>
修改的程式回寫至 repo:
    git push

--------------------
列出 stash 清單
    git stash list
將 working copy 暫存
    git stash
取出最後一次執行暫存的 stash
    git stash pop

--------------------
產生備份
    git bundle create <filename> --all
還原至某目錄
    git clone <filename> <foldername>
    至該 folder 內輸入
    git fetch
    git pull

將現有的 repository push 還原至其它 repository
    git push http://<git repo url> +<current branch>:master

--------------------
收拾失控的 repository (objects/pack/ 資料夾內出現一堆 pack file)
    git gc --aggressive
統計 repository objects
    git count-objects -v

2011-11-13

Objective-C 執行緒同步 ( NSCondition )

撰寫多執行緒程式都會碰到資料同步問題,objc 在這邊可使用 NSCondition 來達成,底下是 NSCondition 與 C#,C++用法比較:
Objective-C 的用法如下: 
NSCondition* pLock =[NSCondition new];
[pLock lock];

    //...
}
[pLock unlock];
[pLock release];



C++ 的用法如下:  HANDLE m_Handle =CreateSemaphore( NULL, 1, 1, L"SemaphoreName" );

WaitForSingleObject( m_Handle, nWaitTime );

    //...
}
ReleaseSemaphore( m_Handle, 1, NULL );
CloseHandle( m_Handle );



C# 的用法如下: 
private static AutoResetEvent m_Handle =new AutoResetEvent( true ); 
m_Handle.WaitOne(); 

    //...
}
m_Handle.Set();
其它有關執行緒同步的文章參考這篇

Objective-C 多執行緒 ( NSOperationQueue )

objc 的 NSOperationQueue 跟 Thread Pool 很類似,用起來也非常的容易,這邊把 Operation 看成 Thread Task , Operation Queue 則看成 Thread Pool 。
底下舉一個簡單的例子:主執行緒使用另一個執行緒印出 “i am taskClass” 字串
//taskClass 負責印出 “i am taskClass” 字串 
@interface taskClass : NSOperation {
}
//main 繼承於 NSOperation, 執行緒啟動時將執行這個函數
-(void) main;
@end


 
@implementation taskClass
-(void) main
{
    NSAutoreleasePool* nsap =[NSAutoreleasePool new];
    NSLog(@"i am taskClass");
    [nsap drain];
}
@end



//主程式
int main (int argc, const char * argv[])
{
    NSAutoreleasePool* nsap =[NSAutoreleasePool new];

    //建立 NSOperationQueue
    NSOperationQueue* nsoq =[NSOperationQueue new];

    //設定最多同時執行的執行緒數
    [nsoq setMaxConcurrentOperationCount:10];

    //建立 taskClass
    taskClass* myTaskClass =[taskClass new];

    //將 taskClass 丟給 NSOperationQueue
    //NSOperationQueue 會分配執行緒去執行 taskClass 的 main 函數

    [nsoq addOperation:myTaskClass];

    //等待 Queue 裡所有的 Operation 執行完畢
    [nsoq waitUntilAllOperationsAreFinished];
   
    [myTaskClass release];
   
    [nsoq release];
   
    [nsap drain];
}
此外,假如 Operation 執行的程式屬於無限迴圈,則在主程式要結束時,可用 cancelAllOperations 函數來通知 Queue 裡的 Operation 中斷迴圈並結束程式,舉例如下:
@interface taskClass : NSOperation {
}
-(void) main;
@end


@implementation taskClass
-(void) main
{
    //檢查 Cancelled 是否為 true, 否則繼續執行
    while ([self isCancelled]==false) {
        //迴圈工作... 
    }
}
@end


//主程式
int main (int argc, const char * argv[])
{
    NSAutoreleasePool* nsap =[NSAutoreleasePool new];

    NSOperationQueue* nsoq =[NSOperationQueue new];
    [nsoq setMaxConcurrentOperationCount:10]; 

    taskClass* myTaskClass =[taskClass new]; 
    [nsoq addOperation:myTaskClass];


    //通知所有執行中的 Operation 中斷執行
    [nsoq cancelAllOperations]; 

    [nsoq waitUntilAllOperationsAreFinished];

    [myTaskClass release];

    [nsoq release];

    [nsap drain];
}

2011-11-07

Objective-C dot(.) 與 arrow(->)

objc 在這裡跟 C++ 一樣,可以透過 (.) 及 (->) 來存取類別(class) 的成員 “變數”,但在 objc 的 property 機制影響之下,有些地方可能會搞不清楚。底下做了一些整理。
假如目前有一個 class 如下:
定義:
@interface classA :NSObject{
@private
    int val;
@public
    int pubVal;
   
}

-(void) initVal: (int) newVal;
-(void) printVal;
@end

實作:
@implementation classA
@synthesize val, pubVal;
-(void) initVal:(int)newVal
{
    val =newVal;
}

-(void) printVal
{
    NSLog(@"val=%d", val);
}

@end
dot(.) 與 arrow(->) 的操作:
classA* bbb =[classA new];
//dot notation
//設定值

bbb.pubVal =5;        //dot 透過 property 機制存取, 同等於 [bbb setPubVal:5];
bbb.val =6;              //dot 透過 property 機制存取, 同等於 [bbb setVal:6];
(*bbb).pubVal =7;    //dot 可直接存取 @public member
//(*bbb).val =8;      //Error, 不是 @public member
//取值
int tmpVal;
tmpVal =bbb.pubVal;      //tmpVal =7,同等於tmpVal =[bbb pubVal];
tmpVal =bbb.val;           //tmpVal =6,同等於tmpVal =[bbb val];
tmpVal =(*bbb).pubVal;  //tmpVal =7
//tmpVal =(*bbb).val;  //Error, 不是 @public member
//arrow notation
//設定值

bbb->pubVal =5;     //arrow 可直接存取 @public member 
//bbb->val =5;             //Error, 不是 @public member
//取值
tmpVal =bbb->pubVal;   //tmpVal =7
//tmpVal =bbb->val;     //Error, 不是 @public member

//使用函數操作
//設定值

[bbb setPubVal:5];  //setPubVal 函數由 property 機制自動產生
[bbb setVal:6];        //setVal 函數由 property 機制自動產生
//取值
tmpVal =[bbb pubVal];
tmpVal =[bbb val];

[bbb initVal:10];
[bbb printVal];

[bbb release];
執行的結果為:
val=10

2011-11-04

Objective-C SEL ( Selector )

暫時先“想像” objc 的 SEL 就像是 C 的函數指標(但在 objc 裡另外還有 IMP, 其定義同等於 C 的函數指標),例如現在有一個類別如下:
定義:
@interface classA :NSObject{
@private
    int val;
}

-(void) initVal: (int) newVal;
-(void) printVal;
@end


實作內容:
@implementation classA
-(void) initVal:(int)newVal
{
    val =newVal;
}

-(void) printVal
{
    NSLog(@"val=%d", val);
}

@end
SEL ( Selector ) 的操作範例如下:
id ppp =[classA new];
[ppp initVal:99];
SEL printPP1 =@selector(printVal);
SEL printPP2 =NSSelectorFromString(@"printVal");

if ([ppp respondsToSelector:printPP1])
    [ppp performSelector:printPP1];

if ([ppp respondsToSelector:printPP2])
    [ppp performSelector:printPP2];

[ppp release];
其中的 printPP1, printPP2 皆指向 classAprintVal 函數, 因此 SEL 的產生方式可以有 @selector 或是 NSSelectorFromString 兩種。
執行的結果為:
val=99
val=99