2014年2月11日 星期二

Chrome 繼續瀏覽上次開啟的網頁 / Reopen the pages that were open last

Remember all the pages in Chrome is an important function to me. Usually, you just check the "Reopen the pages that were open last", then completed.


Step1.


Step2.


Chrome is a program, it can open many windows, and these window contain a lot of tab pages. Reopen the pages that were open last only work, when the program is terminated (Exit the program/Close the computer). 

Chrome in Microsoft, close window ==  program is terminated
Chrome in Mac,         close window  --> program still running

So, If you use chrome in XP/Windows7, close window is not big deal. Double click to run the program, all tabs are back. 


But, if you use chrome in Mac, 
close the window and the program still running.


And all tabs never back.


Remember next time, 
  • Command + Q
  • Command + tab + Q
   To terminate chrome program, or just close the OS (Do not close the chrome windows).  All tabs will be reopen.

2014年1月26日 星期日

Automatic Reference Counting in Xcode

Xcode 4.2 之前沒有ARC,要自己retain, release, autorelease ,去管理記憶體。
Xcode 5.0 之後,專案預設就已經改為都使用ARC,要取消還得另外去設定,官方文件,用ARC可以節省很多的時間,的確。



Without ARC

官方文件,物件的 reference counting (retainCount) 決定何時物件將所佔的記憶體歸還給系統,當建立物件時,retainCount即為1,retain +1,加進到 array 或是UI元件時也 +1, release -1,如果 retainCount為0時,物件消失。

手動管理記憶體很麻煩,常常忘了在 dealloc中release,造成memory leakage (記憶體慢慢流失),或是殺過頭重複釋放物件 (整個程式crash),所以後來出現了 autorelease,只要記得將物件加入至autorelease pool,當pool被清掉時,在池中的每個物件 retainCount -1。

如果物件的取得不是以下的方式,那它已經之前都呼叫過autorelease,被放入池中了,和同伴一起開發程式時,應遵守回傳物件先autorelease,好有效地管理記憶體。
  • alloc
  • new
  • copy
  • mutableCopy
Variables
  • __strong
  • __unsafe_unretained
  • __autoreleasing

Property attribute
  • assign  :  簡單的替換變數,通常用在基礎型別(非物件)。
  • retain   :  用在物件,retainCount +1,確保物件在程式運行時不會被清掉。
  • strong  :
  • copy    :  通常用在新資料為mutable,而原資料為immutable時,可以維持原資料。


With ARC


Variables
  • __strong (預設)         : 在物件還需要使用時,盡可能不被清理掉,當不需要時就回收。
  • __weak                    : 當沒有strong references 指向它時,dealloc and automatically becomes nil,這是ARC新增的最重要的 qualifier 。
  • __unsafe_unretained : 和__weak類似,只是沒有自動指向nil。
  • __autoreleasing        : 通常接受pass by reference的物件,並加入autorelease pool。

Property attribute
  • assign  :          等同於   __unsafe_unretained
  • strong  : (預設)等同於  __strong
  • copy    :          如上
  • weak   :          等同於  __weak

IBOutlet

       習慣上設定為 weak,因為加到view上的這些元件,view已經指向它們,retainCount也自動加上1,如果設定為 strong,將形成 strong reference cycles,永遠殺不掉。至於最上層的物件,例如UIViewController's view outlet, or NSWindowController's window outlet則是 strong

2013年8月23日 星期五

Uva 100 - The 3n+1

問題網址
有幾點要考慮:
  1. 讀取的行數不是單行
  2. 每行的兩個數值,不一定是前小後大
#include <stdio.h>
int cycleLength(int number);
int main()
{
  int i, j, input1, input2;
 
  while( scanf("%d %d",&input1, &input2) != EOF ){
  
      //檢查與調整前後大小
      if(input1 < input2){
          i = input1;
          j = input2;
      }else{
          i = input2;
          j = input1;
      }
  
  
      int maxCycleLength = 0;
      long int x;
      
      for ( x = i; x <=j ; x++){
          int c = cycleLength(x) ;
          if (c > maxCycleLength){
              maxCycleLength = c ;
          }
      }
      printf("%d %d %d\n",input1,input2, maxCycleLength );
 }
 
 
 return 0;
}

int cycleLength(int number)
{
    int c = 1;
    while(number!=1){
        if(number%2==1){
            number = 3*number +1;
            c++;
        }else{
            number = number/2;
            c++;
        }
    }
 return c;
}


解了此題,但是速度太慢(run time:0.612),要嘗試用別種方法

2013年8月16日 星期五

Objective-C Protocols

要求類別一定要實現某些方法時,需要用的到 protocol,代理人模式中 (delegate)常常見到,因為類別在成為另一個類別的代理時,必須實作一些方法以達成代理人的角色。而Objective-C中,因為沒有多重繼承,利用 protocol可以使一個類別具有多重型別的方法。

舉個例子,我們可以定義一些 protocols,@protocol 和 @end 之中宣告要實現的方法,方法的預設值都是required,使用關鍵字@optional將它之下的變成不是必須的,如果是使用新增檔案的方式加入protocol,預設這些 protocols也遵守 (<>) NSObject這個 protocol 。

Behavior.h

@protocol <NSObject>
@optional
-(void)fly;
@required
-(void)run;
-(void)sleep;
@end

Think.h

@protocol <NSObject>
-(void)getRabbit;
-(void)escape;
@optional
-(void)calculate;
@end

然後建立一個類別 Dog , conform/adopt  these protocols,有多個 protocols,用逗點隔開

Dog.h

@interface Dog : NSObject <Behavior, Think>

@end

Dog.m

@implemention Dog
-(void)run
{
    ........
}
-(void)sleep
{
    ........
}
-(void)getRabbit
{
    ........
}
-(void)escape
{
    ........
}
@end

想確認某個物件是否confirm protocol,可以這樣作

id someObject;
......
if ([someObject confirmsToProtocol : @protocol(Think) ] == YES){
    // do something
}

用來宣告型別遵守某些 protocol

id <protocol3, protocol2> someObject ;

2013年8月15日 星期四

Objective-C -- 多型 Polymorphism

polymorphism is a programming language feature that allows values of different data types to be handled using a uniform interface. The concept of parametric polymorphism applies to both data types and functions.
.. from wiki

透過相同的界面進行不同的操作,多型可以應用在資料型別與方法上

書中的解釋更為簡單,Same name, Different Class,不同的類別,相同的名稱,舉個例子,就像是同樣都是叫,鴨子類別中的叫可能是呱呱呱,狗的類別的叫則是汪汪汪。

Animal.h
#import <Foundation/Foundation.h>

@interface Animal : NSObject
{
    NSString *_name;
}
-(void)bray;
@end
Animal.m
#import "Animal.h"

@implementation Animal

-(void)bray
{
    NSLog(@"A......");
}

@end

Duck.h
#import "Animal.h"

@interface Duck : Animal

@end
Duck.m
#import "Duck.h"

@implementation Duck

-(void)bray
{
    NSLog(@"Caw..Caw..Caw.....");
}

@end
Dog.h
#import "Animal.h"

@interface Dog : Animal

@end
Dog.m
#import "Dog.h"

@implementation Dog

-(void)bray
{
    NSLog(@"Wow...Wow..www");
}

@end
main.m
#import <Foundation/Foundation.h>
#import "Animal.h"
#import "Duck.h"
#import "Dog.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        
        id foo;
        //First subclass
        foo = [[Duck alloc]init];
        [foo bray];
        //Second subclass
        foo = [[Dog alloc]init];
        [foo bray];
        
    }
    return 0;
}

輸出結果:




main.m 當中的 id 是objective-C中泛指所有類別的型別,在其他的語言中,如果沒有這種型別,id 改為 Animal一樣可以,而在Objective-C中兩者都可以使用。
foo變數先指到Duck之後指向Dog,雖然方法名稱都是一樣,但是會根據個別類別中的方法去表現。多型的優點就是,不需要取很多的方法名稱,鴨子叫,狗叫,貓叫...,只要執行時去判斷是哪個類別,在找出相對應的方法即可。

Dynamic typing, dynamic binding

前者是指在執行的過程中,物件動態決定屬於哪個類別,後者則是根據哪種類別去執行方法,用上述的例子來說明

foo = [[Dock] alloc] init];   // dynamic typing
[foo bray];                         // dynamic binding

In runtime決定型別固然很強大,但也有缺點,首先在編譯時,complier無法檢查是否有相對應的方法存在,相反地,如果是用靜態型別 static typing,complier 會確保每個方法對應到正確物件,這可以讓我們在編譯時就發現錯誤而不是在執行的時候,因為你永遠不知道使用者會如何操作,意謂者你不可能測試完所有的可能 ; 再者,使用大量的  id,會讓程式的可讀性降低。

2013年8月14日 星期三

Objective-C Inheritance

繼承總要有個來源,在Objective-C 中, NSObject 是所有的類別的源頭,所以時常可以看到
@interface ClassA : NSObject
    ................
@end

self, super
-(id)init
{
    self = [super init];
    if(self) {
        // Initialize code here
    }
    return self;
}

在建構子中,我們常常這樣寫,self 表示自己,super則是父類別,而這段程式是先使用父類別的建構子,如果生成成功,進行子類別的初始化工作,最後回傳。

@class

在類別中要使用別的類別,通常我們都在.h檔中去import另一個類別的標頭檔,
#import "ClassB.h"  // ClassA.h
也可以使用@class這個關鍵字去告訴complier,會更有效率的多
@class ClassB     // ClassA.h
這裡會用到ClassB這個類別,你不用知道它的內容是什麼,儘管編譯過就是了。但事情沒這麼簡單,如果在ClassA.m檔中,有用到ClassB的方法,這時候編譯器怎麼會知道ClassB中的方法內容,就會出現錯誤。



把ClassA.m 檔中匯入ClassB.h檔就可以解決這個問題

#import "ClassB.h"   // ClassA.m

那為何不一開始就在ClassA.h中,直接import ClassB.h檔就好了呢,是啊!!這樣不是多此一舉嗎~~所以使用時機是當你不會用到另一個類別的方法時,用 @class節省編譯很多時間。

另外,有一種情況是非用不可,那就是 circular inclusions,
#import "ClassB.h"  // ClassA.h
#import "ClassA.h" //  ClassB.h

這裡就需要用到@class,就不會再編譯的階段一直無窮的交互import。下面的例子,因為都有用到對方的方法,所以在.m中都需要 import 對方的.h檔。

ClassA.h
#import <Foundation/Foundation.h>
@class  ClassB;
@interface ClassA : NSObject
{
    NSString *name;
    ClassB *b;
}

-(NSString *)name;
-(NSString *)theNameOfB;

@end
ClassA.m
#import "ClassA.h"
#import "ClassB.h"

@implementation ClassA
-(id)init
{
    self = [super init];
    if (self) {
        name = @"A";
    }
    return self;
}

-(NSString *)name
{
    return name;
}
-(NSString *)theNameOfB
{
    if (!b) {
        b = [[ClassB alloc]init];
    }
    return b.name;
}
@end

ClassB.h
#import <Foundation/Foundation.h>
@class ClassA;

@interface ClassB : NSObject
{
    ClassA *a;
    NSString *name;
}

-(NSString *)name;
-(NSString *)theNameOfA;

@end
ClassB.m
#import "ClassB.h"
#import "ClassA.h"

@implementation ClassB


-(id)init
{
    
    self = [super init];
    if (self) {
        name = @"B";
    }
    return self;
    
}

-(NSString *)name
{
    return name;
}

-(NSString *)theNameOfA
{
    if (!a) {
        a = [[ClassA alloc]init];
    }
    return a.name;
}

@end

main.m
#import <Foundation/Foundation.h>
#import "ClassA.h"
#import "ClassB.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        ClassA *a = [[ClassA alloc]init];
        NSLog(@"ClassA use classB method, the name of ClassB : %@",[a theNameOfB]);
        
        ClassB *b = [[ClassB alloc]init];
        NSLog(@"ClassB use classA method, the name of ClassA : %@",[b theNameOfA]);
    }
    return 0;
}


輸出結果

2013年8月13日 星期二

Objective-C Enumerated Data Types

enum 

列舉的優點就是將整數與符號名稱作連接,讓程式的可讀性變好,容易維護,而不需要去記某個數字代表的意義。
enum color{ red = 1, orange, yellow, green, blue, indigo, purple};

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        
        enum color displayColor = blue;
        NSString *displayColorStr;
        
        switch (displayColor) {
            case red:
                displayColorStr = @"紅";
                break;
            case orange:
                displayColorStr = @"橙";
                break;
            case yellow:
                displayColorStr = @"黃";
                break;
            case green:
                displayColorStr = @"綠";
                break;
            case blue:
                displayColorStr = @"藍";
                break;
            case indigo:
                displayColorStr = @"靛";
                break;
            case purple:
                displayColorStr = @"紫";
                break;
                
            default:
                displayColorStr = @"數值有誤";
                break;
        }
        
        NSLog(@"目前的顯示器顏色為:%@",displayColorStr);
    }
    return 0;
}

Anonymous enum 匿名列舉

enum {red = 1, orange, yellow, green, blue, indigo, purple} displayColor ;

沒有名稱,變數緊接著宣告,使用時機,當你懶得取名稱時 :) (大誤)
而宣告時一直打enum也挺煩的,這時可以用 typedef 關鍵字。

typedef

typedef enum {red = 1, orange, yellow, green, blue, indigo, purple} Color ;

Color display = red;