Git 在 Mac OSX 10.11 El Capitan 下更新

今天看到了件好像算蠻大條的事情(轉自保哥的臉書):

這是個遍及全平台的漏洞,如果使用者不小心clone到加料的remote,或是也push了被加料過的repo到其他的remote,可以造成git去執行攻擊者的程式。

而且這個漏洞直到目前最新的2.7.4版本才被修復,因此勢必得更新了。

不過Mac OSX都是內建Git的,即使透過Homebrew(簡稱brew)安裝了最新版Git,在終端機使用"git --version"指令,依然還是會顯示內建的版本。
這是由於OSX的路徑優先權比較高,因此透過brew所安裝的的git,必須要把自己的路徑給加到系統的路徑清單裡,讓系統先找到我們自己安裝的版本,這樣就會讓系統指向brew安裝的2.7.4版本。
*其實透過"which git"指令,就會知道git的安裝路徑在哪裡。

那就開始吧!

首先可以先確認一下自己預設的路徑是哪些,使用"echo $PATH"指令,
我的會是出現這樣的回應:
「/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin」
以冒號為分隔,我的預設路徑是以下這幾個
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

而我去Homebrew的官方網站看到,透過brew的安裝的套件都會放在"/usr/local/Cellar"路徑底下,所以我找到了新版git的安裝路徑為"/usr/local/Cellar/git/"

那我們來增加一下brew安裝git的路徑吧。

首先開啟終端機,然後在家目錄底下,直接用 "vi .bash_profile" 指令,直接叫vi編輯器開一個名字叫做.bash_profile的檔案。
然後再貼上以下的文字

export PATH="/usr/local/Cellar/git/:$PATH"

做得事情很簡單,就只是在原有的預設路徑前面再增加了自行安裝的git的路徑,記得也要用冒號分隔。

增加完畢以後,把終端機關閉重啟,再使用"echo $PATH",前面應該就會出現剛剛加入的路徑,以我的狀況就是
/usr/local/Cellar/git/:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

然後再用 "git --version" 指令確認,就會變成"git version 2.7.4"了,更新完成

越南3G - VN MOBIFONE iPhone設定方式

  • 起因 員工旅遊去了越南,原本預定要購買的VINAFONE賣完了,於是店家給了 VN MOBIFONE; 但是賣出去以後就一問三不知,iPhone插上以後,因為此電信商並未提供iOS設定檔的關係, 所以變得無法使用,不過Android會直接套用設定檔。

一般網路上找到的,傳送內容為「DATA ON」的訊息到號碼「999」,就會開通服務,
在當下那些機場賣SIM卡的櫃檯人員全部沒做阿.......只會跟你說不能分享!
不能分享個屁! Android都直接開了!

以下提供直接設定的方式:

設定-》行動網路-》行動數據網路

APN: m-wap
使用者名稱:mms
密碼:mms

然後照著圖中的方式輸入,就會出現個人熱點的功能了。

iPhone個人熱點,透過USB連結無法使用的問題

前陣子用 高美濕地 優勝美地用得好好的,但是iTunes更新之後,iPhone就沒辦法透過USB將網路分享給Mac了,原因是USB網路分享的驅動程式的數位簽署有問題。

測試方法

打開位於「應用程式」> 「工具程式」的「終端機」,複製貼上以下指令:
(會要求輸入登入的密碼)

sudo kextutil /System/Library/Extensions/AppleUSBEthernetHost.kext

如果終端機出現「Code Signing Failure: not code signed」之類的錯誤訊息,就是這問題了。

解決方法

(隨便開個Finder視窗,按下螢幕上方的「前往」> 「前往檔案夾」,然後輸入以上路徑,就可以直接跳到該目錄了)


(應該過個幾秒,Mac OS會提示驅動程式無法使用,按確定就好,不用管它。)

  • 回到終端機,繼續輸入以下指令

    sudo chown -R root:wheel /System/Library/Extensions/AppleUSBEthernetHost.kext

  • 然後繼續輸入以下指令

    sudo kextload /System/Library/Extensions/AppleUSBEthernetHost.kext

  • 最後,重新用USB連接iPhone和Mac,應該就可以用了;還是不行的話重開機看看。

-------------後續更新-------------
不幸的,這方法在10.10只要重新開啟XCode,就會被要求更新組件,更新過後就又不能用了......
不過只要更新到10.11,這問題就會直接被修正,所以趕快備份重整更新更快,全面優化的10.11吧!!

期待又失望的Chromecast

M的公司送了他們一人一支Chromecast,之前就一直很好奇這小東西能做到什麼程度,
又是Google本家出品,更是相當令人期待......
本來是覺得可以嘗試用用新東西很開心的,但是令人失望
Chromecast,第一個問題就是找不到我的Airport Express的無線網路訊號,
住處附近大約可以搜尋到四~五個無線網路訊號,
但是它只找的到兩個,其中一個是朋友的Time Capsule訊號,
在試了一個多小時以後放棄,我還是用方便的Apple TV就好吧,
尤其不久之前買了新的Airport Express替換已經開始衰退的舊款AE,
Airport工具程式一偵測到,馬上就進入自動替換的頁面,幾下按鍵就無縫接軌,
那種方便跟貼心的使用者體驗,才是蘋果讓人回不去的關鍵阿。

(後續更新)
後來又不曉得為什麼又找得到了,不知是否附近無線網路訊號也很多,導致干擾的關係?
有幾個星期用chromecast+videostream投影了一些動畫,效果還不錯;
但是沒過多久,就又搜尋不到無線網路訊號了,也就把它收起來了。

看來這項產品最適合的還是搭配Youtube使用吧。

Effective Objective-C 2.0中文版讀書心得-主題1、11、29

主題01-熟悉Objective-C的根源:

Objective-C,是C語言的超集合,也就是說,它是基於C語言誕生的物件導向語言,跟C語言自然是百分百相容;在XCode裡面使用Objective-C寫作時,C語言是可以直接混寫並被編譯的。

開發者自己的形容:「就像是一層蓋在C語言上的薄紗」

雖然發展歷史悠久(1983年誕生),但因為只有Apple使用它作為主要開發語言,因此使用的只有Apple或Mac相關社群,直到近幾年Apple開創了行動裝置及App Store風潮後,使用者才有了突發性增加。

Objective-C的物件導向概念及語法,衍生自Smalltalk,與其他物件導向語言的差異是:

它採用的是「訊息傳遞」(messaging)架構,而非「函式呼叫」(function calling);而Smalltalk即為訊息傳遞架構的始祖。

維基百科有句話蠻貼切:

與其說是物件互相呼叫方法,不如說是物件之間傳遞訊息更為精確

也因此,它的語法與其他物件導向語言比起來相當怪異,呼叫物件功能的句型,是用方括號包起來的,也就是smalltalk的語法:

[someObject doThThingWithParameterpara1  WithParameterpara2];
   接收者         方法名稱:          參數1     方法名稱:   參數2

加上此語言在描述上,都是採用長而明確的名稱,不使用簡寫,所以常被其他語言經驗的人覺得麻煩而冗長,但這反而造就了極佳的可讀性

以我來說,以後應該都會維持這樣的習慣,
以保證可讀性,畢竟簡寫到最後大概很可能出現ghost variables

而訊息傳送架構,最關鍵的差異則為:C++等函式呼叫架構的語言,是由編譯器決定的;但是Objective-C,則是在執行時(Runtime)才動態的決定哪段程式碼要被執行,編譯器甚至不管被傳送的物件型別為何,反而是在執行時期才查詢,透過動態繫結機制來進行這些工作。

實際上,Objective-C大部分的繁重工作,不是由編譯器進行,而是透過Runtime元件進行的
Runtime其實就是一組程式碼(可以在類別裡import <objc/>就能看見該資料夾)

裡面包含了Objective-C所有的記憶體管理方法、物件的宣告、訊息的轉送機制;透過Runtime元件,膠合所有的程式碼(反過來說,所有撰寫的程式碼都會與它連結),只要Runtime被更新,應用程式的效能便跟著提昇,而透過編譯器進行較多工作的語言,則需要重新編譯過,才能得到效能改善。

由於Objective-C是C語言的超集,如果想寫出高效的Objective-C程式的話,還是必須理解C語言的記憶體模型,以及C語言的指標(pointer);這對了解Objective-C的參考計數為什麼要那樣運作很有幫助,也牽涉到為什麼Objective-C要使用指標來參照或指涉物件。

Objective-C的物件變數都是存放於記憶體堆疊段(stack)的指標,指向某個存放於堆積段(heap)的實體。  
Objective-C Runtime透過稱為「參考計數」(reference count)的記憶體管理架構,來配置及消滅物件的記憶體配置。

而對於非物件型別,如int、float、double、char等等,通常會採用c結構的方式儲存,如CGRect型別。

主題11-理解objc_msgSend的角色:

繼承自smalltalkObjective-C,與其他OO語言最大的差異就是「訊息傳遞」
在Objective-C的術語中,呼叫物件中的方法,叫做「傳遞訊息」,訊息具有名稱或選擇器(selector),接受參數,可以回傳值。

C語言的函式(function)是靜態繫結,編譯時位置就被寫死,速度較快;
Objective-C的方法(method)是動態繫結,要到執行時才會知道會呼叫哪一個方法,但是同時也要額外讀取方法的位址。

如同主題1所提到的,Objective-C的核心功能都是在執行時期才決定,透過Runtime元件動態產生、連結,但是底層依然是簡單的舊式C函式;可以在類別裡import <objc\/message.h>標頭檔,就可以點進去看了

Objective-C的方法:

id returnValue = [someObject messageName:parameter];

其中someObject被稱為接收者(receiver),
messageName: 被稱為選擇器(selector),
parameter就是參數
而選擇器結合參數,就是訊息了。

(receiver與selector,在起因於方法傳遞錯誤引起的錯誤訊息中,會常常出現這兩個單字)

當編譯器看到訊息後,就會轉成在message.h所定義的objc_msgSend函式,此函式就是C函式

void objc_msgSend(void /* id self, SEL op, ... */ )

第一個參數self,是接收者的位址
第二個參數op,就是選擇器SEL就是選擇器型別

類別中也可以使用SEL變數來傳遞方法位址

剩下的複數參數就是訊息的參數,以上面的方法來說,就是parameter

當Objective-C物件的方法被呼叫時,就會透過這個函式開始進行以下步驟:

  • 尋找接收者所屬類別是否有此方法,有的話就跳進該實作
  • 該類別沒有的話,就順著繼承結構回逤到超類別階層繼續尋找
  • 到最後都沒有的話,就由訊息轉送機制介入(message forwarding)。(在主題12解說)
    基本上找到的結果,都會快取在該類別的fast map中,所以不會是效能瓶頸的原因。
    
    而message.h裡面,也看的到一些針對特定狀況所使用的函式,例如:
  • 傳遞C struct (objc_msgSend_stret
  • 浮點數值(objc_msgSend_fpret)
  • 傳遞給父類別(objc_msgSendSuper
    這些函式特意設計的非常相似,就是為了要讓尋找實作的效率變高,尤其在連續搜尋時,能夠利用尾端呼叫最佳化的方式減少對stack區段的負載, 以減少記憶體負擔。
    

主題29-理解參考計數:

記憶體管理,一直都是所有OO語言的重要概念(感覺所有程式幾乎都是在跟記憶體容量搏鬥),了解各程式語言的記憶體管理模型,對寫出有效率、無臭蟲的程式至關重要。

目前Objective-C的記憶體管理,從iOS5之後預設都是使用自動參考計數(Auto Reference Count)來管理,之前則都是手動參考計數(Manual Reference Count),但是了解手動參考計數還是必要的。

參考計數(Reference Count)與垃圾收集(Garbage Collection)是不一樣的機制喔

「參考計數」簡單來說就是:

  • 每個物件都會有一個計數器,可以遞增或遞減
  • 當你想讓物件持續存在的時候,就遞增這個計數器
  • 當你用完這個物件的時候,就遞減這個計數器
  • 但是當物件的計數器遞減到0的時候,就表示這個物件已經沒有任何東西需要使用他了,該物件就會被「標記」為可以被銷燬,也就是該物件實體所在的記憶體區塊,隨時都有可能被覆寫。
  • 注意:當計數器遞減到0以後,就不能再被遞增了
  • 注意:因為計數為零,只是標記為可銷燬,但未必會立即銷燬,因此要注意計數為零後不要再去存取該物件實體,不然會出現不好找出發生點的程式崩潰。

參考計數最主要有三個方法:

  • retain 遞增參考計數
  • release 遞減參考計數
  • autorelease 稍後才遞減保留計數,也就是在自動釋放緩衝池(autorelease pool)進行排放(drain)方法的時候。 (主題34會講到autorelease pool)
  • 還有另一個:retaincount 可以取得目前該物件的參考計數的值,但是官方不建議使用,也不能作為精準的參考計數判斷。

參考計數的幾個基本運作:

*當物件被建立的時候,參考計數至少為1
*然後當這個物件不再被特定程式碼關注的時候,就呼叫release或autorelease來遞減計數,一旦計數為0,當初指向此物件實體的的參考就失效。

在應用程式的生命週期中,可以看做是很多物件被建立起來,然後彼此關連(參考);
如果物件A中存放了指向物件B的強式參考(strong reference),則物件A被稱為擁有(own)物件B;
強式參考會使得物件B一直到它被使用完為止後,才會被釋放。

在MRC的狀況下的範例:

NSMutableArray *array = [[NSMutableArray alloc] init];  //array物件參考的保留計數至少為1

NSNumber *number = [NSNumber numberWithInt:1337];  //number參考的保留計數至少為1
[array addObject: number]; //number的保留計數再加1
[number release]; //現在不再需要number物件,因此release減1,但是array依然在參考,物件並未被標記銷燬。

/* 使用array做了某些事情 */

[array release]; //做完以後遞減array的保留計數

這段程式碼只能在關閉ARC的專案裡面跑,因為開啟ARC會禁用retain及release方法。

注意:盡量不要對已經release後的物件進行操作,被標記可銷燬的物件未必會在第一時間消失,而且,因為物件太早釋放變成zombie object,導致後續存取失敗產生的bug,很難偵錯。

ARC的使用則比較簡單,只需要把確定不再使用的物件指向nil即可進行釋放。

而透過特性存取器(property)的strong特性的強式參考,所產生的setter方法就像這樣:

-(void)setFoo : (id)foo{
  [foo retain];  //先將傳入的新值保留
  [_foo release];  //再釋放舊的Foo
  _foo = foo; //最後將新的值賦給實體變數_foo
}
  • 變數名稱前線加上底線是直接存取實體變數,而不透過存取器
  • 其實_foo指向的,就是heap中存放的物件實體,只是不經過存取器。
  • 不能在init方法或setter\getter方法中透過存取器(self.)取得變數。

這順序非常重要,不能顛倒,如果先釋放了舊值,結果傳進來的參數剛好也是相同的值,這樣就會導致物件實體被釋放,結果_foo就變成了懸宕指標(殭屍物件,實體早已不存在)

自動釋放緩衝池(Auto Release Pool)

說到Objective-C的參考計數,最重要的功能就是這個,使用者除了自己手動傳遞release訊息之外,也可以傳遞autorelease訊息,讓auto release pool在稍後的某個時間點替使用者釋放該物件。
這種方法尤其常用在:當你的方法需要回傳物件的時候。

例如以下範例:

-(NSString *)getString{
   NSString *string = [NSString stringWithFormat: @”I am this : %@” , self];
   return string;
}

在MRC的狀況下,string應該要在回傳以後進行release,但是return之後方法就跳出了,而回傳:

return [string release]; //錯誤方式,不可以先release之後才回傳

其實就跟先把 string release之後再回傳,其實是一樣危險的方式(可能在回傳之前,就已經被釋放),這時候就可以使用:

return [string autorelease];

來延遲string物件被釋放的時機,這樣它會在緩衝池進行drain(排放)之前存活,也就能回傳給當初呼叫此方法的物件。

保留循環

但是參考計數還是有一個相當棘手的情節:保留循環
例如有三個物件A、B、C;A參考B、B參考C、C參考A,

於是這三個物件的保留計數絕對不會是0,即使這三個物件已經沒有與其他物件相關聯,但是因為循環參照,所以不會被釋放,造成memory leak,這在有垃圾收集(GC)的語言中也被稱為孤島效應,但是GC能夠處理這種情況;參考計數則需要使用弱式參考避免這種情形,或是另外強迫放棄保留,才能解決這種狀況。

[黑蘋果]PC安裝Clover EFI與Hackintosh心得

勞動節的前一天,四年的i7-850 ES+P55平台退役,顯示卡GTX 560 Ti燒掉還短路...
如果不是Power有保護住,應該當場就發爐了。
(所以好的Power真的很重要;以後再缺錢也不買返修品顯卡了==)

於是經過一個多小時的研究之後,選出了最便宜的清單,
至於為什麼會選出這樣的清單,很簡單,因為我沒錢(倒地

Read on