顯示具有 程式開發(Object-C) 標籤的文章。 顯示所有文章
顯示具有 程式開發(Object-C) 標籤的文章。 顯示所有文章

2011年8月31日 星期三

IOS 取得系統執行環境(IPHONE/IPAD)

Use UIDevice-Extension written by Erica Sadun. A very comprehensive class: http://github.com/erica/uidevice-extension/blob/master/UIDevice-Hardware.m
 
 
系統資訊: 

[[UIDevice currentDevice] name]              // eg. "Brock's iPhone"
[[UIDevice currentDevice] model]             // eg. @"iPhone", @"iPod Touch"
[[UIDevice currentDevice] localizedModel]    // localized version of model
[[UIDevice currentDevice] systemName]        // eg. @"iPhone OS"
[[UIDevice currentDevice] systemVersion]     // eg. @"3.2"
[[UIDevice currentDevice] uniqueIdentifier]  // UDID, a unique string to identify the device

範例程式:
Each of the above lines will return an NSString. To which you can do a string comparison like so:

NSString *model = [[UIDevice currentDevice] model];
NSLog(@"Current device model: \"%@\"", model);



其他參考資訊


http://www.drobnik.com/touch/2009/07/determining-the-hardware-model/ You will need to modify this to use the right hardware number for the iPad. Taken from the link above:

2011年8月11日 星期四

Object C - String

============== 字串搜尋 ================
比對字串內容 - string2 去比對 string1內容
NSString *string1 = @"我是個大笨蛋";
NSString *string2 = @"笨蛋";
NSRange range = [string1 rangeOfString:string2];

//print出來
NSLog(@"位置:%d || 字串相同長度:%d", range.location, range.length);


NSRange range = [字串 rangeOfString:字串];
range.location 為所在位置
range.length 為字串相同長度

由以上的code可以得到一長串的句子中哪幾個字是你要的
是從哪一個字元開始,長度為何

※如果一串字中有好幾個重複的字 ex:我是個超級大笨蛋笨蛋笨蛋
他只會找到地一個笨蛋


============== 字串比對 ================
比對兩個字串是否相同
NSString *myString = @"我是個大笨蛋";
NSString *string1 = @"無敵大笨蛋";
NSString *string2 = @"我是個大笨蛋";

//結果為false / NO
if( [myString isEqualToString:string1 ] )

//結果為true / YES
if( [myString isEqualToString:string2 ] )


[字串 isEqual:字串] or [字串 isEqualToString:字串]
在比對字串時上面兩個用法都可以用
用法詳細區別請去看官方library...

============== 抽取字串 ================
從字串開頭開始擷取到指定位置
很抽象對吧...由範例比較好懂

NSString *string1 = @"我是個笨蛋";
NSString *string2 = [string1 substringToIndex:2];

//print "我是"
NSLog(@"string2:%@",string2);

[字串 substringToIndex:數字];
由上面這範例可以清楚了解到所print出來就是從字串頭開始算你要幾個字

--
當然也可以從想要的地方開始找
NSString *string1 = @"我是個笨蛋";
NSString *string2 = [string1 substringFromIndex:3];

//print "笨蛋"
NSLog(@"string2:%@",string2);


[字串 substringFromIndex:數字];
從某一個字開始找字串

--
任意取出字串中想要的部份
NSString *string1 = @"我是個笨蛋";
NSString *string2 = [string1 substringWithRange:NSMakeRange(1, 4)];

//print 是個笨蛋
NSLog(@"string2:%@",string2);


[字串 substringWithRange:NSMakeRange(起始點(數字), 終點(數字))];
就可以直接取得想要的部份


============== END ================

2011年7月19日 星期二

Object-C 進階學習[ 異常情況(Exceptions) ]

  • 異常處理只有 Mac OS X 10.3 UP 才支援。
  • CupWarningException.h
    #import <Foundation/NSException.h>
    
    @interface CupWarningException: NSException
    @end
  • CupWarningException.m
    #import "CupWarningException.h"
    
    @implementation CupWarningException
    @end
  • CupOverflowException.h
    #import <Foundation/NSException.h>
    
    @interface CupOverflowException: NSException
    @end
  • CupOverflowException.m
    #import "CupOverflowException.h"
    
    @implementation CupOverflowException
    @end
  • Cup.h
    #import <Foundation/NSObject.h>
    
    @interface Cup: NSObject {
        int level;
    }
    
    -(int) level;
    -(void) setLevel: (int) l;
    -(void) fill;
    -(void) empty;
    -(void) print;
    @end
  • Cup.m
    #import "Cup.h"
    #import "CupOverflowException.h"
    #import "CupWarningException.h"
    #import <Foundation/NSException.h>
    #import <Foundation/NSString.h>
    
    @implementation Cup
    -(id) init {
        self = [super init];
    
        if ( self ) {
            [self setLevel: 0];
        }
    
        return self;
    }
    
    -(int) level {
        return level;
    }
    
    -(void) setLevel: (int) l {
        level = l;
    
        if ( level > 100 ) {
            // throw overflow
            NSException *e = [CupOverflowException
                exceptionWithName: @"CupOverflowException"
                reason: @"The level is above 100"
                userInfo: nil];
            @throw e;
        } else if ( level >= 50 ) {
            // throw warning
            NSException *e = [CupWarningException
                exceptionWithName: @"CupWarningException"
                reason: @"The level is above or at 50"
                userInfo: nil];
            @throw e;
        } else if ( level < 0 ) {
            // throw exception
            NSException *e = [NSException
                exceptionWithName: @"CupUnderflowException"
                reason: @"The level is below 0"
                userInfo: nil];
            @throw e;
        }
    }
    
    -(void) fill {
        [self setLevel: level + 10];
    }
    
    -(void) empty {
        [self setLevel: level - 10];
    }
    
    -(void) print {
        printf( "Cup level is: %i\n", level );
    }
    @end
  • main.m
    #import "Cup.h"
    #import "CupOverflowException.h"
    #import "CupWarningException.h"
    #import <Foundation/NSString.h>
    #import <Foundation/NSException.h>
    #import <Foundation/NSAutoreleasePool.h>
    #import <stdio.h>
    
    int main( int argc, const char *argv[] ) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        Cup *cup = [[Cup alloc] init];
        int i;
    
        // this will work
        for ( i = 0; i < 4; i++ ) {
            [cup fill];
            [cup print];
        }
    
        // this will throw exceptions
        for ( i = 0; i < 7; i++ ) {
            @try {
                [cup fill];
            } @catch ( CupWarningException *e ) {
                printf( "%s: ", [[e name] cString] );
            } @catch ( CupOverflowException *e ) {
                printf( "%s: ", [[e name] cString] );
            } @finally {
                [cup print];
            }
        }
    
        // throw a generic exception
        @try {
            [cup setLevel: -1];
        } @catch ( NSException *e ) {
            printf( "%s: %s\n", [[e name] cString], [[e reason] cString] );
        }
    
        // free memory 
        [cup release];
        [pool release];
    }
  • output
    Cup level is: 10
    Cup level is: 20
    Cup level is: 30
    Cup level is: 40
    CupWarningException: Cup level is: 50
    CupWarningException: Cup level is: 60
    CupWarningException: Cup level is: 70
    CupWarningException: Cup level is: 80
    CupWarningException: Cup level is: 90
    CupWarningException: Cup level is: 100
    CupOverflowException: Cup level is: 110
    CupUnderflowException: The level is below 0
  • NSAutoreleasePool 是一個記憶體管理類別。
  • Exceptions(異常情況)的丟出不需要擴充(extend)NSException 物件,你可簡單的用 id 來代表它: @catch ( id e ) { ... }
  • 還有一個 finally 區塊,它的行為就像 Java 的異常處理方式,finally 區塊的內容保證會被呼叫。
  • Cup.m 裡的 @"CupOverflowException" 是一個 NSString 常數物件。在 Objective-C 中,@ 符號通常用來代表這是語言的衍生部分。C 語言形式的字串(C string)就像 C/C++ 一樣是 "String constant" 的形式,型別為 char *。

Object-C 進階學習( Class level access )

        當你想計算一個物件被 instance 幾次時,通常有 class level variables 以及 class level functions 是件方便的事。

  • ClassA.h
    #import <Foundation/NSObject.h>
    
    static int count;
    
    @interface ClassA: NSObject
    +(int) initCount;
    +(void) initialize;
    @end
  • ClassA.m
    #import "ClassA.h"
    
    @implementation ClassA
    -(id) init {
        self = [super init];
        count++;
        return self;
    }
    
    +(int) initCount {
        return count;
    }
    
    +(void) initialize {
        count = 0;
    }
    @end
  • main.m
    #import "ClassA.h"
    #import <stdio.h>
    
    int main( int argc, const char *argv[] ) {
        ClassA *c1 = [[ClassA alloc] init];
        ClassA *c2 = [[ClassA alloc] init];
    
        // print count
        printf( "ClassA count: %i\n", [ClassA initCount] );
        
        ClassA *c3 = [[ClassA alloc] init];
    
        // print count again
        printf( "ClassA count: %i\n", [ClassA initCount] );
    
        [c1 release];
        [c2 release];
        [c3 release];
        
        return 0;
    }
  • output
    ClassA count: 2
    ClassA count: 3
  • static int count = 0; 這是 class variable 宣告的方式。其實這種變數擺在這裡並不理想,比較好的解法是像 Java 實作 static class variables 的方法。然而,它確實能用。
  • +(int) initCount; 這是回傳 count 值的實際 method。請注意這細微的差別!這裡在 type 前面不用減號 - 而改用加號 +。加號 + 表示這是一個 class level function。(譯注:許多文件中,class level functions 被稱為 class functions 或 class method)
  • 存取這個變數跟存取一般成員變數沒有兩樣,就像 ClassA 中的 count++ 用法。
  • +(void) initialize method is 在 Objective-C 開始執行你的程式時被呼叫,而且它也被每個 class 呼叫。這是初始化像我們的 count 這類 class level variables 的好地方。

Object-C 牛刀小試 (存取權限)

權限問題
  • 預設的權限是 @protected
  • Java 實作的方式是在 methods 與變數前面加上 public/private/protected 修飾語,而 Objective-C 的作法則更像 C++ 對於 instance variable(C++ 術語 data members)的方式。
  • Access.h
    #import <Foundation/NSObject.h>
    
    @interface Access: NSObject {
    @public
        int publicVar;
    @private
        int privateVar;
        int privateVar2;
    @protected
        int protectedVar;
    }
    @end
  • Access.m
    #import "Access.h"
    
    @implementation Access
    @end
  • main.m
    #import "Access.h"
    #import <stdio.h>
    
    int main( int argc, const char *argv[] ) {
        Access *a = [[Access alloc] init];
    
        // works
        a->publicVar = 10;
        printf( "public var: %i\n", a->publicVar );
    
        // doesn't compile
        //a->privateVar = 100;
        //printf( "private var: %i\n", a->privateVar );
    
        [a release];
        return 0;
    }
  • output
    public var: 10
  • C++ 中 private: [list of vars] public: [list of vars] 的格式,它只是改成了@private, @protected, 等等。

Object-C 牛刀小試[ 建立 Class, 建構子(Constructors)]

延續上述範例
  • Fraction.h
    ...
    -(Fraction*) initNumerator: (int) n OtherParameter1: (int) p1;
    
    ...
  • Fraction.m
    ...
    -(Fraction*) initNumerator: (int) n OtherParameter1: (int) p1 
    {
        self = [super init];
    
        if ( self ) {
            [self setNumerator: n andDenominator: d];
        }
    
        return self;
    }
    ...
  • main.m
    #import <stdio.h>
    #import "Fraction.h"
    
    int main( int argc, const char *argv[] )
     {
        // create a new instance
        Fraction *frac = [[Fraction alloc] init];
        Fraction *frac2 = [[Fraction alloc] init];
        Fraction *frac3 = [[Fraction alloc] initNumerator: 5 OtherParameter1: 10];
    
        // set the values
        [frac setNumerator: 5];
        [frac setDenominator: 10];
    
        // combined set
        [frac2 setNumerator: 5 andDenominator: 10];
    
        // print it
        printf( "The fraction is: " );
        [frac print];
        printf( "\n" );
    
        printf( "Fraction 2 is: " );
        [frac2 print];
        printf( "\n" );
    
        printf( "Fraction 3 is: " );
        [frac3 print];
        printf( "\n" );
    
        // free memory
        [frac release];
        [frac2 release];
        [frac3 release];
    
        return 0;
    }
  • output
    The fraction is: 1/3
    Fraction 2 is: 1/5
    Fraction 3 is: 3/10
  • @interface 裡的宣告就如同正常的函式。
  • @implementation 使用了一個新的關鍵字:super
    • 如同 Java,Objective-C 只有一個 parent class(父類別)。
    • 使用 [super init] 來存取 Super constructor,這個動作需要適當的繼承設計。
    • 你將這個動作回傳的 instance 指派給另一新個關鍵字:self。Self 很像 C++ 與 Java 的 this 指標。
  • if ( self ) 跟 ( self != nil ) 一樣,是為了確定 super constructor 成功傳回了一個新物件。nil 是 Objective-C 用來表達 C/C++ 中 NULL 的方式,可以引入 NSObject 來取得。
  • 當你初始化變數以後,你用傳回 self 的方式來傳回自己的位址。
  • 預設的建構子是 -(id) init。
  • 技術上來說,Objective-C 中的建構子就是一個 "init" method,而不像 C++ 與 Java 有特殊的結構。

Object-C 牛刀小試 (建立 Class, 多重參數)

由之前範例延伸學習
  • Fraction.h
    ...
    -(void) setNumerator: (int) n andDenominator: (int) p1;
    ...
  • Fraction.m
    ...
    -(void) setNumerator: (int) n andDenominator: (int) p1 {
        numerator = n;
        denominator = p1;
    }
    ...
  • main.m
    #import <stdio.h>
    #import "Fraction.h"
    
    int main( int argc, const char *argv[] ) {
        // create a new instance
        Fraction *frac = [[Fraction alloc] init];
        Fraction *frac2 = [[Fraction alloc] init];
    
        // set the values
        [frac setNumerator: 5];
        [frac setDenominator: 10];
    
        // combined set
        [frac2 setNumerator: 5 andDenominator: 10];
    
        // print it
        printf( "The fraction is: " );
        [frac print];
        printf( "\n" );
    
        // print it
        printf( "Fraction 2 is: " );
        [frac2 print];
        printf( "\n" );
    
        // free memory
        [frac release];
        [frac2 release];
    
        return 0;
    }
  • output
    The fraction is: 5/10 = 0.500000
    Fraction 2 is: 5/10 = 0.500000
  • 這個 method 實際上叫做 setNumerator:OtherParameter1:
  • 加入其他參數的方法就跟加入第二個時一樣,即 method:label1:label2:label3: ,而呼叫的方法是 [obj method: param1 label1: param2 label2: param3 label3: param4]
  • Labels 是非必要的,所以可以有一個像這樣的 method:method:::,簡單的省略 label 名稱,但以 : 區隔參數。並不建議這樣使用。

Object-C 牛刀小試 (建立 Class)

@interface
  • Fraction.h
    #import <Foundation/NSObject.h>
    
    @interface Fraction: NSObject {
        int numerator;
        int denominator;
    }
    
    -(void) print;
    -(void) setNumerator: (int) n;
    -(void) setDenominator: (int) d;
    -(int) numerator;
    -(int) denominator;
    @end
    • NSObject:NeXTStep Object 的縮寫。因為它已經改名為 OpenStep,所以這在今天已經不是那麼有意義了。
    • 繼承(inheritance)以 Class: Parent 表示,就像上面的 Fraction: NSObject。
    • 夾在 @interface Class: Parent { .... } 中的稱為 instance variables。
    • 沒有設定存取權限(protected, public, private)時,預設的存取權限為 protected。設定權限的方式將在稍後說明。
    • Instance methods 跟在成員變數(即 instance variables)後。格式為:scope (returnType) methodName: (parameter1Type) parameter1Name;
      • scope 有class 或 instance 兩種。instance methods 以 - 開頭,class level methods 以 + 開頭。
    • Interface 以一個 @end 作為結束。
@implementation
  • Fraction.m
    #import "Fraction.h"
    #import <stdio.h>
    
    @implementation Fraction
    -(void) print {
        printf( "%i/%i = %f", numerator, denominator,((float)numerator/(float)denominator));
    }
    
    -(void) setNumerator: (int) n {
        numerator = n;
    }
    
    -(void) setDenominator: (int) d {
        denominator = d;
    }
    
    -(int) denominator {
        return denominator;
    }
    
    -(int) numerator {
        return numerator;
    }
    @end
    • Implementation 以 @implementation ClassName 開始,以 @end 結束。
    • Implement 定義好的 methods 的方式,跟在 interface 中宣告時很近似。
方法呼叫
  • main.m
    #import <stdio.h>
    #import "Fraction.h"
    
    int main( int argc, const char *argv[] ) {
        // create a new instance
        Fraction *frac = [[Fraction alloc] init];
    
        // set the values
        [frac setNumerator: 5];
        [frac setDenominator: 10];
    
        // print it
        printf( "The fraction is: " );
        [frac print];
        printf( "\n" );
    
        // free memory
        [frac release];
    
        return 0;
    }
  • output
    The fraction is: 5/10 = 0.500000
    • Fraction *frac = [[Fraction alloc] init];
      • 在 Objective-C 中呼叫 methods 的方法是 [object method],就像 C++ 的 object->method()。
      • Objective-C 沒有 value 型別。所以沒有像 C++ 的 Fraction frac; frac.print(); 這類的東西。在 Objective-C 中完全使用指標來處理物件。
      • 這行程式碼實際上做了兩件事: [Fraction alloc] 呼叫了 Fraction class 的 alloc method。這就像 malloc 記憶體,這個動作也做了一樣的事情。
      • [object init] 是一個建構子(constructor)呼叫,負責初始化物件中的所有變數。它呼叫了 [Fraction alloc] 傳回的 instance 上的 init method。這個動作非常普遍,所以通常以一行程式完成:Object *var = [[Object alloc] init];
    • [frac setNumerator: 1] 非常簡單。它呼叫了 frac 上的 setNumerator method 並傳入 1 為參數。
    • 如同每個 C 的變體,Objective-C 也有一個用以釋放記憶體的方式: release。它繼承自 NSObject,這個 method 在之後會有詳盡的解說。

Object-C 牛刀小試 (Hello DylnaHouse)

hello.m
#import <stdio.h>

int main( int argc, const char *argv[] ) {
    printf( "Hello DylnaHouse\n" );
    return 0;
}
輸出結果
Hello DylnaHouse

註解:
  • 在 Objective-C 中使用 #import 代替 #include
  • Objective-C 的預設副檔名是 .m

iPhone 軟體開發 初期準備

iPhone+AppStore  的架構衍化:


早期 iPod+iTunes Music Store     --- > 現在 iPhone+AppStore



iphone / mac 兩個基本配備,可以從 Apple 的官網點選【購買】進去看。

軟體開發部份就不用花費了,因為 Apple 給開發人員免費的開發工具 Xcode,實在比 Visual Studio 還好用!
可以到 http://developer.apple.com/ 下載。

要學 iPhone 程式就從 http://developer.apple.com/iphone/ 開始。

按照 http://developer.apple.com/iphone/ 的指導一步一步進行,看它提供的內容,多做多練習就會了。

史丹佛大學也有一組課程 ,CS 193P 配合影片、講義、範例程式等教材,也是快速入門的方法。

上個月有買一本國人翻譯的【iPhone SDK 開發範例大全】,只是為了支持去買,偶爾會拿來看一看。讀英文手冊會比較慢的朋友,可以參考看看這本書,不過為了寫好程式,還是建議看英文的。

程式語言是用 Objective-C,你可以參考 好好學 Objective-C 2.0 這一篇
實在是比 C++ 還簡單!讓我這樣形容:很接近 Java 與 Delphi.
當然,有物件導向程式設計觀念的更好!

歡迎加入 iPhone 軟體開發的行列,也歡迎加入 Mac OS X 的軟體開發陣容!