Objective-C 入門指南 - 建構子

凡是自己設計的類別 (class) 繼承自 NSObject ,建立新物件 (object) 前都得傳遞 NSObject 的 alloc 訊息,然後利用同是 NSObject 的 init ,或自行改寫或設置的 init ,才能真正建立物件




對比其他物件導向程式語言 (object-oriented programming language) ,例如 Java , alloc 等同 new 的作用,然而 Java 中的建構子 (constructor) 可以說是一種特殊的方法 (method) ,但不是方法, Objective-C 的 init 卻是道道地地的方法。


現在我們要來開始設計 Encrypt 類別的 init ,我們不打算改寫 NSObject 的 init ,而是另外設計專屬於 Encrypt 的 initRandomEncrypt ,這樣一來,方法名稱能夠更符合語意。程式如下
#import <Foundation/Foundation.h>
#import "Encrypt.h"

@implementation Encrypt

@synthesize cArray, oArray;

- (id) initRandomEncrypt
{
    // 設置 y = a * x + b 中的 a 與 b
    int a = 0;
    int b = 0;
    do {
        a = arc4random() % 10;
        b = arc4random() % 10;
    } while (a % 2 == 0);
    
    // 建立 oArray 及 cArray
    oArray = [NSArray arrayWithObjects: 
              @"a", @"b", @"c", @"d", @"e", @"f", @"g", 
              @"h", @"i", @"j", @"k", @"l", @"m", @"n", 
              @"o", @"p", @"q", @"r", @"s", @"t", @"w", 
              @"v", @"u", @"x", @"y", @"z", nil];
    cArray = [NSMutableArray arrayWithCapacity: 26];
 
    // 製作密碼表 cArray
    int n = 26;
    char c = 'a';
    int i, d, ci, count, m;
    for (i = 0, count = c;i < n;i++) {
        ci = count;
        d = ci * a + b;
        m = d % n;
        [cArray addObject: [oArray objectAtIndex: m]];
        count++;
    }
 
 // 回傳 self
    return self;
}

- (NSString *) toEncode: (NSString *) s
{}

- (NSString *) toDecode: (NSString *) s
{}

@end

/* 《程式語言教學誌》的範例程式
   http://pydoing.blogspot.com/
   檔名:Encrypt.m
   功能:示範 Objective-C 程式 
   作者:張凱慶
   時間:西元 2012 年 7 月 */


首先,開頭的負號表示實體方法 (instance method) ,小括弧中的 id 表示回傳值 (return value) 為任意型態,其後 initRandomEncrypt 為方法名稱
- (id) initRandomEncrypt


接下來是取得兩個隨機數 a 與 b ,這裡利用 C 語言的 arc4random() 函數 (function) 得到一個隨機的整數,這裡除以 10 ,使 a 與 b 都得到 10 以內的整數
// 設置 y = a * x + b 中的 a 與 b
int a = 0;
int b = 0;
do {
    a = arc4random() % 10;
    b = arc4random() % 10;
} while (a % 2 == 0);


這裡是利用 do-while 迴圈 (loop) ,因為我們希望 a 得到奇數值,如果 a 是偶數,最後有可能會得到奇怪結果。


initRandomEncrypt 的第二個部份,我們用 NSArray 的類別方法 arrayWithObjects: 與 NSMutableArray 的類別方法 arrayWithCapacity: 各自建立 oArray 與 cArray
// 建立 oArray 及 cArray
oArray = [NSArray arrayWithObjects: 
          @"a", @"b", @"c", @"d", @"e", @"f", @"g", 
          @"h", @"i", @"j", @"k", @"l", @"m", @"n", 
          @"o", @"p", @"q", @"r", @"s", @"t", @"w", 
          @"v", @"u", @"x", @"y", @"z", nil];
cArray = [NSMutableArray arrayWithCapacity: 26];


雖然這樣已經建立 cArray ,但是這樣的 cArray 是空的不包含任何物件,因此第三個部份便是依公式將密碼表製作出來,最後 cArray 便會儲存我們需要的密碼表
// 製作密碼表 cArray
int n = 26;
char c = 'a';
int i, d, ci, count, m;
for (i = 0, count = c;i < n;i++) {
    ci = count;
    d = ci * a + b;
    m = d % n;
    [cArray addObject: [oArray objectAtIndex: m]];
    count++;
}


我們利用 NSMutableArray 的 addObject: 加入物件到 cArray 之中,所加物件是依餘數 m 取得 oArray 中的 NSString 字串物件,也就是利用 NSArray 的 objectAtIndex: 方法。


好了,來寫 demo.m 測試看看吧!
#import <Foundation/Foundation.h>
#import "Encrypt.h"

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    Encrypt *e = [[Encrypt alloc] initRandomEncrypt];
    NSString *o = @"\n\n";
    int i;
    for (i = 0;i < 26;i++) {
        o = [o stringByAppendingString: [[e cArray] objectAtIndex: i]];
    }
    [o stringByAppendingString: @"\n\n"];
    NSLog(o);
 
    [pool drain];
    return 0;
}


/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:demo.m
    功能:示範 Objective-C 程式 
    作者:張凱慶
    時間:西元 2012 年 7 月 */


Build and Go ,結果如下



密碼表做出來囉!繼續來設置編碼功能吧!


中英文術語對照
類別class
物件object
物件導向程式語言object-oriented programming language
建構子constructor
方法method
實體方法instance method
回傳值return value
函數function
迴圈loop


您可以繼續參考
軟體開發


相關目錄
Objective-C 入門指南
Objective-C 教材
首頁



參考資料
Learning Objective-C: A Primer
The Objective-C Programming Language
Cocoa Fundamentals Guide
Coding Guidelines for Cocoa
Advanced Memory Management Programming Guide
Archives and Serializations Programming Guide

1 則留言:

Unknown 提到...

此行 [o stringByAppendingString: @"\n\n"];
我猜您預期的效果應該是有換行,故應該改成
o = [o stringByAppendingString: @"\n\n"];