2010年4月15日 星期四

[PHP] php-5.2.13/ext/gd/libgd/gd_png.c:142: undefined reference to `png_check_sig'

最近常用的工作站的 PHP 更新到 PHP 5.3.2 了,沒想到我自己編的 PHP 5.2.x 就意外中槍落馬,一堆環境變了,而透過 Tarball 重新編譯 PHP 5.2.13 來用時,碰到以下的訊息:


php-5.2.13/ext/gd/libgd/gd_png.c:142:
undefined
reference
to `png_check_sig'


隨意 Google ,原來很多人都碰到了,解法就是修改 php-5.2.13/ext/gd/libgd/gd_png.c 程式碼


142         //if (!png_check_sig (sig, 8)) { /* bad signature */
143         if (!png_sig_cmp (sig, 0, 8)) { /* bad signature */
144                 return NULL;145         }


即可完成處理。真難得還要改 code 啊


順便記錄一下自己編 PHP 5.2.13 所下的指令


./configure --with-apxs2=/path/tmp_for_httpd/bin/apxs --prefix=/path/tmp_for_php --without-pear --with-openssl --enable-mbstring --with-curl --with-imap --with-mcrypt --with-imap-ssl --with-gd --with-jpeg-dir=/path/tmp_for/lib


2010年4月11日 星期日

[遊戲] iPhone 戰略類免費遊戲 - TowerMadness™ Zero

iPhone TM Zero iPhone TM Zero


這是一款免費的攻防遊戲,也就是建立一些堡塔攻擊經過的外星人,以防他們到達目的地並搶走你的羊。此款遊戲也有付費的機制,像是某個建築物要付費才能取得,或是某些地圖要付費才能玩。整體上免費的已經夠玩囉!目前一些地圖的 Hard 模式我都打不贏就是了。









偶爾拿來殺時間也不錯,唯一的缺點大概是讓你的 iPhone 電力不停的下降吧。


2010年4月10日 星期六

領廣告費囉!閒聊 BloggerAds 收益

bloggerads


記得開始用時,是在 2008 年 12 月初吧!我記得寫過幾篇文章記錄:



那時開始,試了 BloggerAds 跟 Google Adsense ,前者很不錯,只要有廣告曝光也有錢,而後者偏向要有人點擊才有比較"看"得出來有廣告費。


googleadsense


看看上面兩張圖,差不多同樣時間申請的廣告,BloggerAds 已經超過 Google Adsense 給的 1.5 倍了(Google Adsense 用的是美金),其中我用 Google Analytics 看過幾眼,我的 blog 的確佔了七、八成是透過 Search Engines 連過來的。(忘了一提,我的 Google Adsense 有分 20% 給 PIXNET)


這也可能跟我使用 Blog 的習慣有關,我一開就把 Blog 定位在"從 Search Engines 連過來的",而不是像一般寫作專家,專門寫給人看得,讓人容易常常注意。這樣也不錯,因為我的 Blog 本身就定位在自己的筆記的,只是稍微懂一點點 Search Engines 的 Ranking 方式,所以有時標題會有點誇大 XD 但我想至少有幫助到別人吧!說到這,令人反感的,則是有人一字不改的再複製我的文章,除了連"來源"都不會標明外,並別說標題了!有時搜尋引擎的結果排序,反而我文章排名還輸對方一大截!因為對方也依照這種方式去抄別人的大站,讓自己的權重變得很高!甚至有人再爬你的文章,你一發表沒多久,他就跟著發表,若仔細計較,一定會讓人火大啦!極有可能是因為我開放全文 RSS 服務,考慮關一下測試看看,畢竟不開發全文對閱讀者也是另一種好處,可以先看看短文,等有興趣再看全文吧!


不過,暫時把心情擺在一旁,現在,我只是為我自己記錄一些東西囉!


guestlog


回過頭聊聊 BloggerAds ,經我的觀察,以我自己的 Blog 一天約 300~700 的瀏覽人潮來說(純粹只以 Pixnet 記錄的),而 300 左右是在週末,超過 300 則是一到五的工作天,這樣下來,一個月可累積約 100 ~ 120 元的廣告費,在此就粗算 550 的人潮可以讓你一個月有 100 元的微薄收入吧!


以我的經驗來說,從一開始一個月 10 元、40 元,然後去年夏天一口氣衝到 90 元時,那時我才想到,廣告的收入可能跟兩者有關:



  • 廣告商

  • 人潮


那時我是猜廣告商在暑期投入的比較多,因為 BloggerAds 也算是會安排廣告給各個 Blog 的,右邊框框我設定是可以顯示三則廣告,但他可是依照手頭上的廣告來分配的,並不是每次都三則,且不是隨時都擺放商業性的廣告,也有公益性的,因此,只有商業性的才會分到錢,算是另類的做公益吧。而人潮的確會影響,但去年暑假時,收入變多時,我覺得只是單純的"廣告商"效應,因為我那時的瀏覽人數並沒有多少,可能 300 上下,在加上我寫的不是吸引別人的文章,因此猜測,廣告商還是影響最多的因素。


隨意閒聊,記得當時有學長也開始玩,他就在那邊想到底要多少人潮才可以當作"月薪",我這邊是一天 600 人潮,約 4.5 元廣告費,那月薪假設 4 萬好了


40,000 ÷ 30 天 ≒ 1,334 元/天
1,334 元/天 × ( 600 人 ÷  4.5 元 ) ≒ 177,866 人/天


大概一天要有快 20 萬人潮來你家!但轉個彎看看其他熱門的部落格,有的一天就有 2,000 人潮,甚至 10,000 以上,如 酪梨壽司的日記 :: 痞客邦 PIXNET :: ,以現在早上快十點,人潮就已超過一萬囉!除此之外,還有一些常常在 PTT 的熱門看板打滾的,如雨狗大神 RainDog :: 痞客邦 PIXNET :: ,一天也可以輕輕鬆鬆破萬的,當然還有當紅的 Facebook、Twitter 和 Plurk 等等囉!我實在很佩服他們花心力去經營,但細節部分就當作商業機密吧!哈,在此不多談以免破壞別人及市場行情。


只不過反推回自己的狀態,我的 blog 還是只是給自己看得為主,筆記用途,頂多偶爾也給 Search Engines 吃吃啦!所以,等我哪天發閒再來試試其他的推廣方式吧!最後,忘了一提,BloggerAds 要滿一千才能提款,而 Google Adsense 則是要滿 100 美金囉!這也是為何我說領錢啦!因為我的 BloggerAds 達到門檻囉!


2010年4月7日 星期三

目標咧?

王功漁港


這張年假時,在彰化王功那邊拍的,已經擺在 blog 的草稿文章區多時。


最近開始學開車,透過在 PTT 揪團駕訓班,也認識了幾位朋友,但就是要有交集才會長久,漸漸地大概只剩早上一起共乘搭車去駕訓班的夥伴會閒聊而已,其中有一位是社會組,剛好跟我念的科系不同,生活有很明確的目標,為了達成那個目標,可以不上 Facebook ,真是厲害,對學生而言,大概就是不玩線上遊戲或是不逛 BBS 吧。而她的目標就是準備多益考試,考得還是法文。不曉的是不是本身對語言沒啥興趣,不要說英文了,連台語我都不怎講,若真的要計較的話,頂多程式語言我還比較想學。


在駕訓班也過了十多天了,很巧地又遇到大學的直屬學妹,反而因此在早上會稍稍閒聊。除此之外,大概是認識教練吧!從一開始我覺得他很嚴肅,練車時不談論其他事,甚至某一天我還以為他有起床氣,再練 S 彎道時,還很大力的轉我的方向盤,然而現在呢?我反而跟他有說有笑,還真奇怪吧!


我想,那大概就像下棋一樣,有時你會是別人的棋子,聽從別人的指令,然而,有時你又會是別人的對手,要適時引起別人的戰鬥力,相處上要避開別人的缺點,更激發出他的優點,甚至適時的示弱,也是一種前進的方式。另外,滿高興可以認識不一樣領域的人,每個人有自己的背景,卻又就像一本無字天書,章節或頁數,可都要靠嘴巴問出來。沒想到高中之後,還會有這種體悟 :P 深深覺得,每個人都存在不一樣隱性的價值,不是當下的身分、地位甚至金錢可以衡量的。


這兩天的工作內容有點類似傳播或資管系所的學生,要統計整理一些東西,對我而言,也算學到不少東西!就像去逛 NOVA 時,你明明知道可以把所有傳單收來比低價,但沒有真正的身體力行,或是做了半套,一切都仍只是空談,值得慶幸的,我沒有變成傳播妹。


至於目標咧?我還沒找到,最近倒有一點彈性疲乏,過個週末應該會好多了!今天下午還騎了公司的腳踏車一下,雖然沒辦到事,但心情有輕鬆一下啦。


2010年4月1日 星期四

iOS 開發教學 - 使用 UITableView & UITableViewController 提供表單服務

除了在 CS 193P iPhone Application Development 看到的教學外,另外還有到詳細的表單教學:iPhone Programming Tutorial: Part 6: Creating custom UITableViewCell Using Interface Builder [UITableView],除此之外,在文章下頭還有操作影片,非常詳盡喔!該篇文章主打教你怎樣透過 Interface Builder 去豐富 UITableViewCell 的樣貌。

只是我看著這種教學方式,感覺有點不實在,甚至照著模仿時,迷失自己。像是忘了物件沒初始化等等的,或是沒去看為啥沒顯示出東西,這些很根本的東西容易遺忘。

以下是筆記自己的操作流程:


  • [Xcode]->[Create a new Xcode project]->[iPhone OS]->[Application]->[Window-based Application]-> 填寫 MyTable 即可

  • 點選到 Class 裡頭(非必要動作,只是讓新增的檔案都在 Class 目錄裡),[Xcode]->[File]->[New File]->[Cocoa Touch Class]->[UIViewController subclass] 並且只勾選 UITableViewController ,取名為 MyTableViewController

如此一來,在 Class 中就會有:

MyTableAppDelegate.h
MyTableAppDelegate.m
MyTableViewController.h
MyTableViewController.m

接著依序先對 MyTableAppDelegate 設定,在對 MyTableViewController 處理:

MyTableAppDelegate.h

#import <UIKit/UIKit.h>
#import "MyTableViewController.h"

@interface MyTableAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    MyTableViewController *myTableController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

MyTableAppDelegate.m

#import "MyTableAppDelegate.h"

@implementation MyTableAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
    myTableController = [[MyTableViewController alloc] init]; // initWithStyle:UITableViewStylePlain
    [window addSubview:myTableController.view];
    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

- (void)dealloc {
    [myTableController release];
    [window release];
    [super dealloc];
}

@end

MyTableViewController.h

#import <UIKit/UIKit.h>

@interface MyTableViewController : UITableViewController {
    NSArray *myData;
}

@end

MyTableViewController.m

#import "MyTableViewController.h"

@implementation MyTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    myData = [[NSArray alloc] initWithObjects:@"GMail" , @"YMail" , @"Hotmail" , @"NUMail" , nil];
  
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
  
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [myData count];
    //return 0;
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  
    static NSString *CellIdentifier = @"Cell";
  
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Updated @ 2012-08-07
    // Sample Code without "cell check" message:
    // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
    //
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
  
    // Set up the cell...
    cell.textLabel.text = (NSString*)[myData objectAtIndex:indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController];
    // [anotherViewController release];
}

- (void)dealloc {
    [myData release];
    [super dealloc];
}

@end

執行成果:

UITableView

以上藍色字樣就是有增加或修改的地方,這是一個非常簡單的清單列表。重要的地方是在於 MVC 架構,在使用 UITableViewController 時,只需要去處理資料的來源(如 NSArray *myData),然後是回傳有多少東西(numberOfRowsInSection),以及顯示項目的處理 tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath ,只要把握住這三個關鍵點,一切就很正常啦!我一開始卡在一直沒東西出來,原因就是忘了去更新 numberOfRowsInSection 函數,它預設是 0 個東西。

熟悉最簡單的東西後,你可以更改 Table 呈現方式,即在 MyTableAppDelegate.m 初始化 myTableController 時,改成:

myTableController = [[MyTableViewController alloc] initWithStyle:UITableViewStyleGrouped]; // 預設為 UITableViewStylePlain

執行的成果:

UITableView Grouped

剩下的,可以去玩玩 Section 部分,讓顯示的清單有分群效果,或是讓 item 有事件,如點下後切換場景等等的。

UITableView Section
(此例只簡單將numberOfSectionsInTableView回傳數字改為2)

@2010/04/13 更新,以下是多個 Section 範例的部份程式碼:

MyTableViewController.h

@interface MyTableViewController : UITableViewController {
     NSMutableArray *dataSource;
}

MyTableViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    dataSource = [[NSMutableArray alloc] init];
  
    NSMutableArray* b1 = [[NSMutableArray alloc] init];
    [b1 addObject:@"1"];
    [b1 addObject:@"2"];
    [b1 addObject:@"3"];
  
    [dataSource addObject:b1];
   
[b1 release];

    NSMutableArray* b2 = [[NSMutableArray alloc] init];
    [b2 addObject:@"A"];
    [b2 addObject:@"B"];
    [b2 addObject:@"C"];
   
    [dataSource addObject:b2];

    [b2 release];

   
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if ( dataSource == nil )
        return 1;
    return [dataSource count];

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger bucketCount = -1;
    NSObject *target_section;
    if ( dataSource == nil )
        return 0;
    if( ( bucketCount = [dataSource count] ) < 1 || bucketCount <= section || (target_section = [dataSource objectAtIndex:section ]) == nil )
        return 0;
    return [ (NSMutableArray*)target_section count ];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  
    static NSString *CellIdentifier = @"Cell";
  
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
  
    // Set up the cell...
    cell.textLabel.text = (NSString*)[ (NSMutableArray*)[dataSource objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
  
    return cell;
}

// 此函數預設沒有,要自己打一下
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSInteger bucketCount = -1;
    NSObject *target;
    if ( dataSource == nil )
        return @"";
    if( ( bucketCount = [dataSource count] ) < 1 || bucketCount <= section || ( target = [dataSource objectAtIndex:section ] ) == nil || (target = [ (NSMutableArray*)target objectAtIndex:0] ) == nil )
        return @"";
    return (NSString*) target;
}

Demo

UITableViewStyleGrouped

UITableViewStyleGrouped

UITableViewStylePlain

UITableViewStylePlain

最後,如果你希望你的 Section 可以透過 index 跳過去,如下圖中右邊的文字

sectionIndexTitlesForTableView

那就再替 MyTableViewController.m 增加一個函數,並且自定各個 section 要顯示的 title 囉!

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    NSArray* sIndex = [[NSArray alloc] initWithObjects:@"0-9", @"A", @"中", @"日", @"法", @"德", nil];
    return
[sIndex autorelease];
}

概念就只是依序點到哪個位置,直接切到該 section 的起頭。

參考資料: