2013年5月1日 星期三

objective-c function 根據參數類型,有不同的行為

在objective-c 函式中,如果傳入的是簡單型別或是常數,函式會自動複製一份傳入的參數,所以之後如果有更改原先的變數,物件內的成員不會受影響;反之如果傳入的不是簡單型別或是常數,函式只會將物件的成員指向同一個位置,如果有更改變數,物件內的成員也跟著變動,這樣解釋有點模糊,看個例子比較清楚。
//XYPoint為自訂的一個類別
@interface XYPoint : NSObject
{
    int x;
    int y;
}
@property int x, y;

-(void)setX:(int) xVal andY:(int) yVal;

@end

@implementation XYPoint

@synthesize x,y;

-(void)setX:(int)xVal andY:(int)yVal
{
    x = xVal;
    y = yVal;
}

@end


//主要的測試類別,成員包含自定類別XYPoint, NSMutableString, int
@interface Foo : NSObject
{
    XYPoint *o;
    NSMutableString *name;
    int X;
}
-(XYPoint *)o;
-(void)setO:(XYPoint *)pt;
-(NSMutableString *)name;
-(void)setName:(NSMutableString *)n;
-(int)X;
-(void)setX:(int)value;
@end

@implementation Foo

-(XYPoint *)o
{
    return o;
}
-(void)setO:(XYPoint *)pt
{
    o = pt;
}

-(NSMutableString *)name
{
    return name;
}
-(void)setName:(NSMutableString *)n
{
    name = n;
}
-(int)X
{
    return X;
}
-(void)setX:(int)value
{
    X = value;
}
@end


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

    @autoreleasepool {
        
        //先準備等一會要傳入Foo的變數
        XYPoint *myPoint = [[XYPoint alloc]init];
        NSMutableString *myName = [[NSMutableString alloc]initWithString:@"Jon"];
        [myPoint setX:100 andY:200];
        int myValue = 10;
        
        //建立一個Foo物件,將成員設定為上述的變數
        Foo *f = [[Foo alloc]init];
        f.o = myPoint;
        [f setName:myName];
        [f setX:myValue];

        NSLog(@"Before change myPoint, f.o.x : %d f.o.y : %d",f.o.x,f.o.y);
        NSLog(@"Before change myName, f.name : %@",f.name);
        NSLog(@"Before change myValue, f.X : %d",f.X);
        
        //更改這些變數,看看是否為影響f內的成員
        [myPoint setX:50 andY:50];
        [myName setString:@"Tom"];
        myValue = 5;

        NSLog(@"After change myPoint, f.o.x : %d f.o.y : %d",f.o.x,f.o.y);
        NSLog(@"After change myName, f.name : %@",f.name);
        NSLog(@"After change myValue, f.X : %d",f.X);
    }
    return 0;
}


結果如下:
Before change myPoint, f.o.x : 100 f.o.y : 200
Before change myName, f.name : Jon
Before change myValue, f.X : 10
After change myPoint, f.o.x : 50 f.o.y : 50
After change myName, f.name : Tom
After change myValue, f.X : 10

2013年4月28日 星期日

Class variable in objective-c

在objective-c中沒有提到class variable,不過可以用static variable實現。

Toy.h

#import <Foundation/Foundation.h>
@interface Toy : NSObject
{
    NSString *name_;
}
@property (nonatomic,retain)NSString *name;
+(int)currentToyNumber;
@end


Toy.m
#import "Toy.h"

static int toyNumber;

@implementation Toy
@synthesize name = name_;
-(id)init
{
    self =[super init];
    if (self) {
        toyNumber++;
    }
    return self;
}
+(int)currentToyNumber
{
    return toyNumber;
}
-(void)dealloc
{
    toyNumber--;
}
@end


main.m
#import <Foundation/Foundation.h>
#import "Toy.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //新增一個Toy
        Toy *toyA = [[Toy alloc]init];
        [toyA setName:@"Apple"];
        NSLog(@"Add toy, currentToyNumber: %d",[Toy currentToyNumber]);
        //再新增一個Toy
        Toy *toyB = [[Toy alloc]init];
        [toyB setName:@"Banana"];
        NSLog(@"Add another toy, currentToyNumber: %d",[Toy currentToyNumber]);
        //刪除一個Toy
        toyA = nil;
        NSLog(@"Delete apple, currentToyNumber: %d",[Toy currentToyNumber]);
        
    }
    return 0;
}

Output的結果如下:

Add toy, currentToyNumber: 1
Add another toy, currentToyNumber: 2
Delete apple, currentToyNumber: 1



用extern改寫,範例如下,其實是用全域變數,已經跟class variable含意不同了。
Toy.h
#import <Foundation/Foundation.h>
extern int currentToyNumber;

@interface Toy : NSObject
{
    
}
@end


Toy.m
#import "Toy.h"

@implementation Toy
-(id)init
{
    self = [super init];
    if (self) {
        currentToyNumber++;
    }
    return self;
}
-(void)dealloc
{
    currentToyNumber--;
}
@end

main
#import <Foundation/Foundation.h>
#import "Toy.h"


int currentToyNumber = 0;

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

    @autoreleasepool {
        
        NSLog(@"CurrentToyNumber : %d",currentToyNumber);
        
        Toy *toyA = [[Toy alloc]init];
        NSLog(@"CurrentToyNumber : %d",currentToyNumber);
        
        Toy *toyB = [[Toy alloc]init];
        NSLog(@"CurrentToyNumber : %d",currentToyNumber);
        
        toyA = nil;
        
        NSLog(@"CurrentToyNumber : %d",currentToyNumber);
    }
    return 0;
}
輸出結果:
CurrentToyNumber : 0
CurrentToyNumber : 1
CurrentToyNumber : 2
CurrentToyNumber : 1

2013年3月26日 星期二

IBOutlet 到底要放在property 還是ivar

最常見的是把IBOutlet放在property
@interface fooViewController : UIViewController {
   UILabel *fooLabel;
}
@property (nonatomic,weak)IBOutlet UILabel *fooLabel;
@end

但也有人放在ivar
@interface fooViewController : UIViewController {
    IBOutlet UILabel *fooLabel;
}
@property (nonatomic,weak)UILabel *fooLabel;
@end

甚至兩個地方都放的
@interface fooViewController : UIViewController {
    IBOutlet UILabel *fooLabel;
}
@property (nonatomic,weak)IBOutlet UILabel *fooLabel;
@end

這些程式碼都不會出錯,不過我還是想知道到底放在哪裡最好,查到了這一篇講得很清楚。
放在property比較有彈性,且編譯的速度快些,官方文件也是推薦放在property,有興趣的人可以看看。

2011年8月25日 星期四

灰熊人 Grizzly man



如果將提姆崔德威爾所拍攝的影片,當成灰熊的生態紀錄片來看,那就同把「老人與海」看作捕魚紀事般。荷西的紀錄片應該歸類於劇情片,它是那麼的主動,帶領著觀眾去收下導演所想要傳達的訊息。

成長在平凡環境中的主角--提姆,就像隨處可見的平凡人一般,在平凡的家中長大,起伏於不上不下的課業成績,沒什麼可吸引旁人目光的特點。唯一擅長的是游泳與跳水,憑藉這個專長申請到一流的大學獎學金,以為從此就像人造衛星開始繞行上了軌道,卻交了壞朋友染上酗酒的惡習,背受了傷,退了學。

在外頭浮沈的提姆,有強烈表演欲望,曾經努力爭取演出的機會,但也都僅限於跑跑龍套般的角色,以為人生從此就像滑下一無止境的緩坡沒什麼希望時,最後在阿拉斯加的曠野裡找到了舞台--灰熊保護者。

鏡頭前,荒野中,那麼的真誠與直率,生動的錄下與灰熊的互動,藉由推廣生態保育的觀念與勇敢和灰熊接觸的形象,讓他成為家喻戶曉的人物。13年的夏日時光,沒有間斷的紀錄與觀察灰熊,這不是簡單的表象的動機可以維持的,需要有一種類似宗教般的信仰。

當他反覆的說他愛那些熊時,我相信那一定是真的,沒有任何虛假,因為他早已變成灰熊,灰熊就是他,他是那麼的嚮往灰熊的世界,迫不急待想融入,認定那裡盡是美好與純真。但這種東西不存在於現實的世界,盜獵者與廣告商侵入了他的領域,管理處的各項規定,熊群間的殘忍、天候的異常,提姆越來越憤怒。

沒有起伏的人生與情緒都不是提姆想要的,他放棄服用鎮定劑,冒險的與灰熊共處,生活在充滿各種表情的日子裡,最後被黑暗所吞食,他應該沒有悔恨,唯一可惜的,是捲入了一個悲劇的女友。片尾,提姆帶領著兩隻小灰熊沿著河越走越遠,另一個世界等待著。

2011年7月17日 星期日

最後想去的地方

朋友的先生在走之前的一天晚上,和孩子說想到中正紀念堂走走, 但是台大醫院離哪有段距離, 最後決定去總統府繞繞, 已經沒辦法走路的他在凌晨三四點由兩個小孩攙扶著, 再看幾眼這個世界,回到醫院沒多久就離開了.....
我想原本要去中正紀念堂的他應該沒有太遺憾, 因為有人陪伴走過日出前最黑暗的時光,是很幸福的.

2011年6月2日 星期四

佩服與羨慕


身高一米五多, 臉不立體, 身材保持地很好, 以普遍的標準來看, 她絕對不算一位美女, 身邊認識的朋友有很多都比她漂亮, 但我從沒看過那樣的自信, 她是個條件沒有很好但努力讓自己向上提升的人。聰明的人考一百分, 高大帥氣的人當模特, 富二代開跑車, 這些都不會令人感動, 只會讓人羨慕, 但我們會佩服王永慶的白手起家, 陶子的幽默慧潔與周傑倫的才華。
當然,還存在另一種人,是讓人又羨慕又佩服的,許多領域中最傑出的人都是如此,因為有些事情光是努力是無法克服的,要成功還得有點天份與運氣的成份。

2011年6月1日 星期三

卓越不是一次性的行為

整晚都有個說話的聲音一直在耳邊嗡嗡作響, 一度懷疑是不是隔壁的室友在看電視, 所以六點不到即醒來, 去外頭裝水聲音不曾停歇, 索性決定去跑步好了, 有一陣子沒有早上起來運動。
早上的健身房真安靜, 三三兩兩的人散步於跑步機上, 我也把腳步放輕, 沉浸在這靜謐中, 外面開始有車輛出現, 睡眼惺忪的小朋友跟著爸媽來到了幼稚園, 滿身大汗的我, 也跑不動了, 淋個浴, 吃早點, 悠閒從容在這打字, 感覺一天能這樣開始真好。
維持運動的習慣不容易, 能每天晨跑或晨泳則更困難, 今天只是曇花一現嗎?! 我開始有點想睡了.......