[Java] Eclipse的偏好設定(操作習慣和好用技巧)

2012-11-15 15 55 03

實在不得不說,Eclipse真的是個很強大的IDE

有些好用快捷鍵在還沒有開始設定偏好設定前先分享一下
這些快捷鍵

Ctrl + Shift + F    自動排版(超好用

Alt + /                 開啟字彙選擇框(自動完成框)
Ctrl + D               刪除一行
Ctrl + /                註解/解除註解多行
Ctrl + B               建置專案
Ctrl + L               到指定行號(一般編輯器都是Ctrl + G)
Ctrl + 1               跳出修正建議框

 

 


其實這篇的產生因為重灌電腦,常常好多Eclipse好用的偏好設定都忘了設定上去
然後選項又超多,分類錯綜複雜 

除了做個備份,也一併分享給大家

這些路徑不用強記,可以憑印象打關鍵字,很多選項就會跳出來了唷

 

 

專案的編碼格式(Encoding)

這我不知為何,Eclipse它的預設值是ANSI

在還沒有專案的時候,可以像我一樣調整成utf-8

但是如果已有專案的話,文字有可能會變亂碼唷

這時候用convertz救援吧

 

路徑:General > Workspace

關鍵字:encoding

2012-11-15 15 57 41

Text file encoding 的地方,文字框打入 utf-8

另外,Build automatically 的地方,我喜歡把勾勾去掉

需要的時候手動按 Ctrl + B 建置專案

 

 

字體大小設定

我雖然沒有老花,但就是不喜歡字體小小的糊在一起,對Eclipse第一個開刀的一定是字體大小

字體大一點,自己看得也舒服

路徑:General > Appearance > Colors and Fonts

關鍵字:font

2012-11-15 15 59 51

在Basic裡的Text Font修改字體大小

如果只是程式碼,其實只要調Text Font就好,其他會跟著Text Font去調整

至於中文字嘛…預設的字型調過了之後,中文字還是很小
這時可能要調字型,至於字型…每個人的適應能力不同

通常是找每個字體間距相等的為佳,這部份留給大家自行嘗試摟 

 

 

自動格式化設定

路徑:Java > Code Style > Formatter

關鍵字:Format

Eclipse最強大的功能就是「自動格式化(Auto Format)」  (灑花)

在coding的時候可以按個快捷鍵 Ctrl + Shift + F

在凌亂的格式,都整得服服貼貼

 

 

因為受大學老師程式碼風格影響,大括弧「 { 」一定要換一行

所以我們就這樣對應調整

2012-11-15 16 03 46

Eclipse預設風格是不給調的,複製一份設定檔即可

按下New,打入一個喜歡的名字

2012-11-15 16 05 23

在Braces裡,除了最後一個之外,其它都設定成Next line
右邊有預覽窗格,可以邊調邊看效果 

 

 

自動完成框

不只是Eclipse,很多整合開發環境(IDE)都會提供自動完成框

尤其是Visual studio,打幾個字就跳出候選字選取框

就像你在用google一樣簡單

因為電腦CPU等等的條件影響,預設不是甚麼鍵都觸發之
但我們可以把他打開

 

路徑:Java > Editor > Content Assist

關鍵字:auto

2012-11-15 16 07 10

這個自動完成的功能,因為受到網路文章的影響

發現大為好用,故分享給大家

我就直接轉載了

 

勾選 "Enable auto-activation" 的選項
Auto activation delay 為提示出現的延遲時間,建議可以設為 0ms (預設是200ms)
Auto activation triggers for Java 為 IDE 遇到何種字元會自動啟動提示,預設只有 dot,請改為 .abcdefghijklmnopqrstuvwxyz(,
Auto activation triggers for Javadoc 在註解區塊中遇到何種字元會啟動提示,預設是 @ 及 #

 

這個Auto activation triggers for Java,如果CPU不夠力的時候,可以調回預設值:點點 「 .

手動按 alt + / 也是會跳出來啦

 

參考:

http://icercat.pixnet.net/blog/post/23671027

 

ADB連接逾時

這個選項是從這裡來的

http://j796160836.pixnet.net/blog/post/29108155

在開發Android,可以用wifi 來做打開除錯 (就像是連接USB一樣)

但這功能需要root

 

最近是遇到當網路環境不穩定時,連接常常逾時(timeout)

所以可以在這裡設定timeout的時間

路徑:Android > DDMS

2012-11-15 15 55 37

 

ADB connection time out (ms): 預設是5000

經由測試,大概改到80000足夠

 

 


將會不定時增加…

[RDP] 遠端桌面使用的常用快捷鍵

因為常常使用遠端桌面,太常忘記了要怎麼按

在遠端桌面按 Ctrl + Alt + Delete 了,就筆記一下

 

本機快速鍵 遠端桌面快速鍵 功能說明
CTRL + ALT + DEL CTRL + ALT + END

顯示 [Windows 安全性] 對話方塊

CTRL + ALT + BREAK

在視窗和全螢幕顯示模式間切換。

Win Key 或 CTRL + ESC

ALT + HOME

顯示 [開始] 功能表。

ALT + TAB

ALT + PAGE UP

從左到右切換視窗
SHIFT + ALT + TAB

ALT + PAGE DOWN

從右到左切換視窗
PrintScreen

CTRL + ALT + 數字鍵上的加號(+)

將遠端的整個螢幕畫面複製回本機。
ALT + PrintScreen

CTRL + ALT + 數字鍵上的減號(-)

將遠端的作用中的螢幕畫面複製回本機。

 

資料來源

http://blog.miniasp.com/post/2008/07/22/The-hotkey-usage-in-Remote-Desktop-environment.aspx

http://windows.microsoft.com/zh-HK/windows-vista/What-shortcut-keys-can-I-use-in-Remote-Desktop-Connection

[JSP] JSP連接MySQL初探

這篇算是因為網友詢問,才會有的一篇文章吧

 

最近也在看JSP的一些寫法

因為還沒有看很懂,所以這一篇一直都沒有寫

用Java跑網頁有二種型態

  • Servlet
  • JSP

Servlet可以算是JSP的前身,可以處理比較複雜的事情
JSP的寫法比較像PHP,那我們就從這裡開始吧

範例不難,但環境設定上頗麻煩的

——————————————————–

環境設定

再開始之前,先講一下環境設定

標題是連MySQL資料庫嘛,所以要有MySQL取得方式我就不細講了

有在寫PHP+MySQL的話,目前在使用的MySQL就大方的借過來用吧

 

 

若是使用整合環境(如appserv、wamp、xampp…等等)

就只需要補上JDK、Tomcat、MySQL Connecter,官方下載在這裡:

JDK

http://www.oracle.com/technetwork/java/javase/downloads/index.html

Tomcat

http://tomcat.apache.org/download-70.cgi

MySQL Connecter for Java

http://www.mysql.com/downloads/connector/j/

選擇你的作業系統看是x86還是x64,選擇對應的檔案安裝

然後用Next大法(一直Next),一路給他裝完

 

如果,你像我一樣覺得這樣裝很凌亂,或是說是新建環境,甚麼都沒有的話

可以採用新版的XAMPP 1.81

http://www.apachefriends.org/zh_tw/xampp.html

這個版本裡面就有附tomcat摟

少一個要補檔的對象

接下來只要下載JDK + MySQL Connecter就行摟!

 

 

個人是建議用JDK+XAMPP的配置,或是整合環境+JDK+官方tomcat

(對了,新版含tomcat的XAMPP不能跟tomcat混裝,路徑會錯亂…)

XAMPP他主要功能有包入Apache HTTP Server、MySQL Server、FileZilla FTP Server、Mail Server、Tomcat Server

細項有php、pear、perl、cgi、phpmyadmin、mbstring、gd….等等(糟糕離題了…)

 

反正,整合環境有他的好處,除了設定檔要自己設定之外

其他大多都設定好了

 

 

MySQL Connector的地方先說明一下

只要下載完畢,解壓縮

取出mysql-connector-java-5.1.22-bin.jar這個檔案就好,壓縮檔裡的其他資料可以不用

(筆者抓到的是Connector/J 5.1.22版本,所以檔案叫做mysql-connector-java-5.1.22-bin.jar

請依照你下載的版本做變化)

然後將它放到tomcat的目錄的lib裡,所以變成

官方Tomcat路徑:

C:\Program Files\Apache Software Foundation\Tomcat 7.0\lib\mysql-connector-java-5.1.22-bin.jar

XAMPP包含tomcat路徑:

C:\xampp\tomcat\lib\mysql-connector-java-5.1.22-bin.jar

 

環境變數

主要有點麻煩的是Java的環境設定

Windows環境變數的方法在這裡:

WinXP在我的電腦按滑鼠右鍵 -> 內容 -> (上方頁籤)進階 -> 環境變數

Win7是在開始 -> 我的電腦按右鍵 -> 內容 -> (在左側欄)進階系統設定 -> (上方頁籤)進階 -> 環境變數

 

要添加這些環境變數

純JAVA環境
———————
JAVA_HOME
C:\Program Files\Java\jdk1.6.0_35
CLASSPATH
.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\jre;%JAVA_HOME%\src
Path
.;%JAVA_HOME%\bin

JAVA環境+Tomcat網頁伺服器環境
———————
JAVA_HOME
C:\Program Files\Java\jdk1.6.0_35
CATALINA_HOME
(官方Tomcat路徑)
C:\Program Files\Apache Software Foundation\Tomcat 7.0
 
(XAMPP包含tomcat路徑)
C:\xampp\tomcat
(二者依環境,擇其一使用) 

CLASSPATH
.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\jre;%JAVA_HOME%\src;%CATALINA_HOME%\lib\servlet-api.jar;%CATALINA_HOME%\lib\mysql-connector-java-5.1.22-bin.jar
Path
.;%JAVA_HOME%\bin

有些地方要注意

如果裡面有值的話(像是Path),打個分號 ; 再連接上去

藍字的地方是他的版本號,要依照你的版本做變化(查看一下該路徑是否有東西)

設定完畢要重新開機(使用者登出再登入)才會生效

這樣就設定完成了

 

弄到這裡可以先測試一下

phpmyadmin是否能正常連線MySQL?(代表php+MySQL正常)

tomcat是否正常啟動? http://localhost:8080/ 有沒有東西?

 

—————————————————————————-

建立範例DB

終於回到程式面了,可以開個資料庫名字叫test_jspdb

執行以下SQL;

CREATE TABLE IF NOT EXISTS `employee` 
`emp_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`emp_name` varchar(100) NOT NULL,
`emp_age` int(11) NOT NULL,
PRIMARY KEY (`emp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;

INSERT INTO `employee` (`emp_id`, `emp_name`, `emp_age`) VALUES
(1, ‘mary’, 20)
(2, ‘amy’, 22);

 

資料表內容很簡單,就只有員工姓名,員工年齡而已

—————————————————————-

 

JSP範例

這時候可以建立一個連線的範例來做了

網站的根目錄在:

C:\xampp\tomcat\webapps\ROOT

C:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\ROOT

在那裡建立一個空檔案db_test.jsp然後貼上以下程式碼。

然後瀏覽 http://localhost:8080/db_test.jsp 看看能不能使用

如果出現can’t load mysql driver代表說MySQL Connector的設定有問題

查看檔案位置是否正確及環境變數設定是否有更新

 

 

 

<%@ page contentType=”text/html;charset=utf-8″%>

<%@ page import=”java.sql.*”%>
<%
try
{
//讀取mysqlDriver驅動程式
Class.forName(“org.gjt.mm.mysql.Driver”).newInstance();

try
{
//連接mysql資料庫

// 資料庫名稱”zend_test”,帳號”root”,密碼”123456″,
// 使用Unicode編碼”true”,字元集”UTF-8″
String db_user=”root”;
String db_pwd=”12345″;
String db_database=”test_jspdb”;
Connection conn= DriverManager.getConnection(“jdbc:mysql://localhost:3306/”+db_database+”?user=”+db_user+”&password=”+db_pwd+”&useUnicode=true&characterEncoding=UTF-8″);

try
{
//建立statement
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
try
{
//建立SQL查詢
String sql=”select * from album”;
ResultSet rs = stmt.executeQuery(sql);

%>

<h2>Employee</h2>
<table border=1>
<tr><th>id</th><th>artist</th><th>title</th></tr>
<%
//顯示資料

while(rs.next())
{
%>
<tr>
<td><%=rs.getString(“id”)%></td><td><%=rs.getString(“artist”)%></td><td><%=rs.getString(“title”)%></td>
</tr>
<%
}
%>
</table>
<%

// 關閉連線
rs.close();
rs = null;
stmt.close();
stmt = null;
conn.close();

}
catch (Exception ex)
{
out.println(“can’t read data”);
out.println(ex.toString());
}
}
catch (Exception e)
{
out.println(“can’t create statement”);
out.println(e.toString());
}
}
catch(Exception e)
{
out.println(“can’t content mysql database”);
out.println(e.toString());
}

}
catch(Exception e)
{
out.println(“can’t load mysql driver”);
out.println(e.toString());
}

%>

 

 寫法跟PHP差不多吧!有個重點要提一下

 

其餘的update insert delete指令可以這樣寫)

String sql = “INSERT INTO `employee` (`emp_name`, `emp_age`) VALUES
(‘mary’, 20),”;

// 執行SQL語法
Statement stmt = conn.createStatement();
stmt.executeUpdate(sql);

 

你可能會疑惑createStatement這個方法

ResultSet.TYPE_FORWARD_ONLY (預設值)

就只能使用next()方法取得下一筆(指標順序定位)

 

ResultSet.TYPE_SCROLL_INSENSITIVE與 ResultSet.TYPE_SCROLL_SENSITIVE

能使用afterLast()、previous()、absolute()、relative()其他方法

有 ResultSet.CONCUR_READ_ONLY與ResultSet.CONCUR_UPDATABLE兩個參數可以設定,前者表示只能讀取 ResultSet的資料,後者表示可以直接使用ResultSet來操作資料庫

(這個部份還沒有驗證,我想應該跟update insert delete指令無關)

 

如果有誤煩請指正

 

參考資料

http://caterpillar.onlyfun.net/Gossip/JavaGossip-V2/ResultSetCursor.htm

http://jjnnykimo.pixnet.net/blog/post/21585335-jsp%E9%80%A3%E7%B5%90mysql%E8%B3%87%E6%96%99%E5%BA%AB%E7%AF%84%E4%BE%8B

http://blog.yam.com/carl44/article/14825336

http://blog.alumni.nctu.edu.tw/plate/web/papermsg.jsp?UI=markcool&PI=96 

[MySQL] 數字10以下的中文數字排序(或是列表排序)

這是網路上參考別人寫的方式,靈機一動想到的

因為想到這個方法覺得很BG且好笑
就當個茶餘飯後的笑話分享給大家

在這之前還是先呼籲一下,

在建立DB的時候,數字就應該用數字的格式儲存

 

不要像我犯同樣的錯誤
拿小寫的中文數字(一二三四五六七八九) 
或是大寫的中文數字(壹貳參肆伍陸柒捌玖拾)

去儲存數字,然後自找苦吃

因為它的ASCII的code大小也沒照順序(所以資料庫的文字排序失效) 

————————————————————

網路上對於MSSQL有個解法
就是使用列表比對的方式

也有人使用自訂函數去parse中文數字然後轉換成對應的數字

也可以利用一個對應的轉換表,用inner join的方式去做

————————————————————

在MySQL裡,我找到一個還不錯的做法:

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_locate

Locate函數:

Locate(欄位名稱, 搜尋比對的字串)

找尋字串中,第一個出現的位置,並回傳其位置

而這位置就是我們要的順序結果(反正多大也不重要,至少相對順序是對的)

如果我有一張表table01

todo  week 
寫作業  一 
買東西  三 
聚餐  二 
看電影  四 

想照星期排序(這就中文數字了吧….Orz)

就這樣下

select *, LOCATE( week,  ‘一二三四五六日’ ) from table01 order by LOCATE( week,  ‘一二三四五六日’ );

聰明的你,就會在phpmyadmin看到這個結果,然後就會跟我一樣大笑XDD

todo  week  LOCATE( week,  ‘一二三四五六日’ )
寫作業  一  1
聚餐  2
買東西  三  3
看電影  四  4

 

理論上,只要是不重複的字串應該都可以適用

拜託鞭小力點…

[Fedora 14-17] 架設VPN Server (pptpd)

安裝PPTPD及相關服務

yum install -y rp-pppoe gcc pptp pptp-setup  ppp ppp-devel
 
安裝方式有二種:
 
RPM安裝(要依照Linux的版本安裝)
 
例如Fedora 14 (32bit)
wget http://poptop.sourceforge.net/yum/stable/fc14/i386/pptpd-1.3.4-2.fc14.i686.rpm
rpm -ivh pptpd-1.3.4-2.fc14.i686.rpm
 
Fedora 14 (64bit)
wget http://poptop.sourceforge.net/yum/stable/fc14/x86_64/pptpd-1.3.4-2.fc14.x86_64.rpm
rpm -ivh pptpd-1.3.4-2.fc14.x86_64.rpm
 
YUM安裝(要依照Linux的版本安裝)
 
rpm -ivh http://poptop.sourceforge.net/yum/stable/fc14/pptp-release-current.noarch.rpm
yum install pptpd
 
 
下載並安裝核心模組
 
 
wget http://sourceforge.net/projects/poptop/files/mppe%20module%20builder/kernel_ppp_mppe-1.0.2%20dkms-2.0.6/kernel_ppp_mppe-1.0.2-3dkms.noarch.rpm/download
 
wget http://downloads.sourceforge.net/project/poptop/mppe%20module%20builder/kernel_ppp_mppe-1.0.2%20dkms-2.0.6/kernel_ppp_mppe-1.0.2-3dkms.noarch.rpm?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fpoptop%2Ffiles%2Fmppe%2520module%2520builder%2Fkernel_ppp_mppe-1.0.2%2520dkms-2.0.6%2F&ts=1341655470&use_mirror=nchc
 
wget http://downloads.sourceforge.net/project/poptop/mppe%20module%20builder/kernel_ppp_mppe-1.0.2%20dkms-2.0.6/dkms-2.0.6-1.noarch.rpm?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fpoptop%2Ffiles%2Fmppe%2520module%2520builder%2Fkernel_ppp_mppe-1.0.2%2520dkms-2.0.6%2F&ts=1341655518&use_mirror=nchc
 
rpm -ivh dkms-2.0.6-1.noarch.rpm
rpm -ivh kernel_ppp_mppe-1.0.2-3dkms.noarch.rpm
 
 
若沒有按照版本安裝會有類似以下錯誤: 
Error! Bad return status for module build on kernel: 3.4.2-1.fc16.x86_64 (x86_64)
Consult the make.log in the build directory
/var/lib/dkms/kernel_ppp_mppe/1.0.2/build/ for more information.
 
Error! Could not locate ppp_generic.ko for module kernel_ppp_mppe in the DKMS tree.
You must run a dkms build for kernel 3.4.2-1.fc16.x86_64 (x86_64) first.
 
========================================================
 
設定PPTPD
 
 
設定Client看到的伺服器IP,以及DHCP分發的IP範圍
vi /etc/pptpd.conf
加入以下:
localip 10.0.0.1
remoteip 10.0.0.10-100
 
—————————————————-
 
設定pptpd的加密方式和發給Client的DNS
vi /etc/ppp/options.pptpd
refuse-pap
refuse-chap
refuse-mschap
 
require-mschap-v2
require-mppe-128
 
ms-dns 168.95.1.1
 
—————————————————-
 
設定帳號密碼(若使用ppp撥號(xDSL),撥號的帳密也會在這裡)
格式為:
帳號、使用的服務、密碼、接受的IP(通常為*號)
中間用空格隔開
 
vi /etc/ppp/chap-secrets
內容大致為:
# client        server           secret             IP addresses
[email protected]”      *         “your password”
test pptpd 12345 *
 
 
—————————————————- 
 
設定系統IP轉發
vi /etc/sysctl.conf
修改
net.ipv4.ip_forward = 1
 
讓系統重新載入設定值
sysctl -p
 
—————————————————-
 
設定防火牆
 
主要是設定讓PPTP的Client能夠NAT上網
請依照對外連線的網路卡代號取代掉ppp0
ppp+的代表用來連接VPN Client的網卡,不需更動
vi /etc/sysconfig/iptables
 
 
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT
 
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
# 其他要開啟服務的port依照格式寫在這裡
 
#—-vpn—-
-A INPUT -i ppp0 -p tcp –dport 1723 -j ACCEPT
-A INPUT -i ppp0 -p gre -j ACCEPT
-A FORWARD -i ppp+ -o ppp0 -j ACCEPT
-A FORWARD -i ppp0 -o ppp+ -j ACCEPT
#—-vpn—-
 
-A INPUT -j REJECT –reject-with icmp-host-prohibited
-A FORWARD -j REJECT –reject-with icmp-host-prohibited
COMMIT
 
—————————————————-
 
重啟防火牆(Fedora 14以上使用)
systemctl restart iptables.service
systemctl restart ip6tables.service
 
重啟防火牆(Fedora 14含以下使用)
/etc/init.d/iptables restart

 

 
========================================================
 
啟動PPTPD等服務
 
 
啟動PPTPD服務
/etc/init.d/pptpd start
重啟PPTPD服務
/etc/init.d/pptpd restart
斷除所有VPN連線
/etc/init.d/pptpd restart-kill
 
 
查看相關的Log
tail -n 30 /var/log/messages
 
查看連線情況
netstat -an | grep :1723 | sort
 
========================================================
 

[ASP]在純ASP中操作陣列產生JSON格式

因為專案需求,需要把原本ASP的資料轉成JSON的格式

我知道ASP是大家動態網頁設計的好夥伴(笑)

(迷之音:ASP都出這麼久了,很多都已經轉成ASP.net了幹嘛這麼執著呢?)

就跟你說是專案需求了嘛(巴落去

這只是我的小小筆記,以免有機會又用上找不到怎麼做
尤其是程式語言對於陣列(Array)的操作方式都不大一樣

我盡量強化大家的JSON概念,盡量不特別提程式碼的部份

——————————–

學JSON格式只有二句話:

物件(object)用大括號 { }

陣列(array)用中括號 [ ]

先記住這概念

——————————–

 

ASP要使用JSON要下載此元件:

http://code.google.com/p/aspjson/

我們只需要他的ASP JSON (for production) 就好:
寫文的時候是JSON_2.0.4.asp 

把他放在你的目錄然後用以下方式引用:

<!–#include file=”JSON_2.0.4.asp”–>

這裡有些範例蠻有用的:

http://code.google.com/p/aspjson/wiki/Samples2

 

引用部份範例來說明

物件寫法

<%
Dim o1
Set o1 = jsObject()

      o1(“name”) = “Tom”
      o1(“lastname”) = “Chen”

o1.Flush
%>

顯示

{“name”:”Tom”,”lastname”:”Chen”}

陣列寫法

<%
Dim o2
Set o2 = jsArray()

      o2(Null) = 2
      o2(Null) = 4
      o2(Null) = 6
      o2(Null) = 8

o2.Flush
%>

顯示

[2,4,6,8]

———————

所以我們學到,宣告空白變數使用Dim

決定是何種型態使用 Set 這個字

不要小看這個關鍵字,他可是很有用的

 

 

最後,當你把資料形態設定為jsObject之後

直接像範例一樣 o(“name”) 直接在括號之中放入新的key值,當成變數來指定

 

而資料形態設定為jsArray的時候

可以像範例一樣用o2(Null) 的方式增加值

 

範例集有提到jsArray和jsObject中的對轉,我覺得不是很重要,所以就不引用了

 

再來看比較tricky的

物件包物件

<%
Dim o3
Set o3 = jsObject()

      Set o3(“person”) = jsObject()
            o3(“person”)(“name”) = “Tom”
            o3(“person”)(“lastname”) = “Chen”

      Set o3(“equipment”) = jsObject()
            o3(“equipment”)(“name”) = “keyboard”
            o3(“equipment”)(“type”) = “electronic”

o3.Flush
%>

顯示

{“person”:{“name”:”Tom”,”lastname”:”Chen”},”equipment”:{“name”:”keyboard”,”type”:”electronic”}}

陣列包陣列

<%

Dim o4
Set o4 = jsArray()

      Set o4(Null) = jsArray()
            o4(Null)(Null) = 0
            o4(Null)(Null) = 2
            o4(Null)(Null) = 4
            o4(Null)(Null) = 6

      Set o4(Null) = jsArray()
            o4(Null)(Null) = 1
            o4(Null)(Null) = 3
            o4(Null)(Null) = 5
            o4(Null)(Null) = 7

o4.Flush
%>

顯示

[[0,2,4,6],[1,3,5,7]]

在陣列包陣列的範例中,就會明顯看到
其實程式它是從上到下,照順序執行

雖然 Set o4(Null) = jsArray() 這二行都一樣
但意義不同

難度慢慢增高摟

陣列包物件

<%
Dim o5
Set o5 = jsArray()

      Set o5(Null) = jsObject()
            o5(Null)(“name”) = “Tom”
            o5(Null)(“lastname”) = “Chen”
      Set o5(Null) = jsObject()
            o5(Null)(“name”) = “Amy”
            o5(Null)(“lastname”) = “Lin”

o5.Flush
%>

顯示

[{“name”:”Tom”,”lastname”:”Chen”},{“name”:”Amy”,”lastname”:”Lin”}]

這JSON格式已經接近資料庫撈出來的格式了

物件包陣列

<%
Dim o6
Set o6 = jsObject()
      o6(“name”) = “Tom”
      o6(“lastname”) = “Chen”

      Set o6(“numbers”) = jsArray()
            o6(“numbers”)(Null) = 2
            o6(“numbers”)(Null) = 4
            o6(“numbers”)(Null) = 5
            o6(“numbers”)(Null) = 6

o6.Flush
%>

顯示

{“name”:”Tom”,”lastname”:”Chen”,”numbers”:[2,4,5,6]}

———————

最後跳過中間的步驟,直接開最後的大絕!

陣列包物件包陣列包物件

心理OS:哪那麼多陣列物件呀~

<%
Dim o7
Set o7 = jsArray()

      Set o7(Null) = jsObject()
            o7(Null)(“name”) = “Tom”
            o7(Null)(“lastname”) = “Chen”

            Set o7(Null)(“report”) = jsArray()

                  Set o7(Null)(“report”)(Null) = jsObject()
                        o7(Null)(“report”)(Null)(“subject”)=”Math”
                        o7(Null)(“report”)(Null)(“score”)=80

                  Set o7(Null)(“report”)(Null) = jsObject()
                        o7(Null)(“report”)(Null)(“subject”)=”English”
                        o7(Null)(“report”)(Null)(“score”)=90

      Set o7(Null) = jsObject()
            o7(Null)(“name”) = “Amy”
            o7(Null)(“lastname”) = “Lin”

            Set o7(Null)(“report”) = jsArray()

                  Set o7(Null)(“report”)(Null) = jsObject()
                        o7(Null)(“report”)(Null)(“subject”)=”Math”
                        o7(Null)(“report”)(Null)(“score”)=86

            Set o7(Null)(“report”)(Null) = jsObject()
                        o7(Null)(“report”)(Null)(“subject”)=”English”
                        o7(Null)(“report”)(Null)(“score”)=88

o7.Flush
%>

顯示

[{“name”:”Tom”,”lastname”:”Chen”,”report”:[{“subject”:”Math”,”score”:80},{“subject”:”English”,”score”:90}]},{“name”:”Amy”,”lastname”:”Lin”,”report”:[{“subject”:”Math”,”score”:86},{“subject”:”English”,”score”:88}]}]

看起來很複雜其實並不然

換成XML的格式就長這樣

<data>

    <student>
        <name>Tom</name>
        <lastname>Chen</lastname>

        <report>

            <subject>
                <name>Math</name>
                <score>80</score>
            </subject>
            <subject>
                <name>English</name>
                <score>90</score>
            </subject>

        </report>
    </student>

    <student>
        <name>Amy</name>
        <lastname>Lin</lastname>

        <report>

            <subject>
                <name>Math</name>
                <score>86</score>
            </subject>
            <subject>
                <name>English</name>
                <score>88</score>
            </subject>

        </report>
    </student>

</data>


做成大家看得懂的表格

成績單1

姓名  Tom Chen 
數學 80 
英文  90 

成績單2

姓名  Amy Lin 
數學 86
英文 88 

在回顧一下上面那二個很噁心的寫法
有困難嗎?有任何讓你造成不舒服的感覺嗎? 

 

 

 

===============================================

以下內容看不懂就算了,沒關係

 

最後看看這資料庫的函式QueryToJSON

http://code.google.com/p/aspjson/wiki/SQLtoJSON

FunctionQueryToJSON(dbc, sql)
       
Dim rs, jsa, col
       
Set rs = dbc.Execute(sql)
       
Set jsa = jsArray()
       
WhileNot(rs.EOF Or rs.BOF)
               
Set jsa(Null)= jsObject()
               
ForEach col In rs.Fields
                        jsa
(Null)(col.Name)= col.Value
               
Next
        rs
.MoveNext
       
Wend
       
SetQueryToJSON= jsa
EndFunction

如果上面都看懂的話,只是把欄位名稱和值,用For each印出來,放進jsObject裡而已

rs.Fields就是取得recordset的欄位物件,用

col.Name  取得欄位名
col.Value  取得值

 

若我資料庫有張表

student

s_id  name  lastname 
Tom  Chen 
 Amy Lin 

report

r_id  s_id  subject  score 
Math  80 
English  90
Math  86
English  88

 

是不是我們的資料庫就可以這樣寫呢?

sql = “select * from student”

Set rs = dbc.Execute(sql)
Set jsa = jsArray()
While Not (rs.EOF Or rs.BOF)
   Set jsa(Null) = jsObject()
   For Each col In rs.Fields
      jsa(Null)(col.Name) = col.Value
   Next

   sql2 = “SELECT subject,score FROM report WHERE s_id=”&rs(“s_id”)
   Set rs2 = dbc.Execute(sql2)

   Set jsa(Null)(“report”) = jsArray()
   While Not (rs2.EOF Or rs2.BOF)
      Set jsa(Null)(“report”)(Null) = jsObject()

      For Each col2 In rs2.Fields
          jsa(Null)(“report”)(Null)(col2.Name) = col2.Value
      Next

      rs2.MoveNext
   Wend

   rs.MoveNext
Wend

[Windows Phone]解決Windows Phone SDK抓不到VS2010完整版的問題

意興來潮來玩一下Windows Phone芒果機的開發

在開發環境的部分,除了有Windows 7

還要另外安裝Windows Phone SDK

 

Windows Phone SDK官網下載:

http://www.microsoft.com/zh-tw/download/details.aspx?id=27570

安裝之後,如果沒有Visual Studio 2010的話,他會很貼心的幫你安裝

Visual Studio 2010 Express供你使用


各位版大,不知道是否像我一樣

本身已經安裝好了Visual Studio 2010

 

在安裝之後仍然出現Express版,而本身完整版卻沒有安裝完成

可以遵循以下步驟:

相關樣版,而這問題可透過以下方式解決

要複製二個地方

 

第一個地方,C#版本的Silverlight for Windows Phone資料夾:

C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEProjectTemplatesCSharpSilverlight for Windows Phone

整個Silverlight for Windows Phone資料夾複製到:

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplatesVisual C#


第二個地方,VB版本的Silverlight for Windows Phone資料夾:

C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEProjectTemplatesVisualBasicSilverlight for Windows Phone

整個Silverlight for Windows Phone資料夾複製到:

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplatesVisual Basic

 

注意路徑中Visual Basic的空格,一個有一個沒有

若你的Win7版本是32位元的,把紅字中的(x86)字樣拿掉就是你的路徑

紅字的使用者名稱代換成你的使用者名稱

所以最後你的

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplates

的 Visual Basic 和 Visual C# 資料夾都會有同名的但內容不一樣的 Silverlight for Windows Phone 資料夾

2012-06-26 10 42 15  

 

 

然後在開始選單中找到 所有程式 > Microsoft Visual Studio 2010 > Visual Studio Tools > Visual Studio 命令提示字元 (2010)

2012-06-26 09 14 22    

在指令鍵入

devenv.exe /setup

不做這個動作的話,在新增的頁面可以看到但不能建立

2012-06-26 10 07 12  


再重開VS2010即可

在檔案 > 新增 > 專案 之中

就會看到新的專案從你的VS2010出現摟

2012-06-26 10 37 12  

 

參考資料:

http://www.dotblogs.com.tw/ian/archive/2012/02/15/69380.aspx

http://mnc363eo.iteye.com/blog/1351962

[MySQL] 如何在phpMyAdmin裡開啟Designer功能

小提示:這是比較進階的文章,不知道等一下的步驟在幹嘛的,就跳過整篇文章吧 

———————————-

想必有用PHP & MySQL寫過網頁吧,想必phpMyAdmin應該是你的好朋友 (笑)

phpMyAdmin裡,其中有個還不錯用的功能就是Designer
可以畫資料庫的關聯圖,對於資料表關聯的了解有很大的幫助

但這功能在之後的版本,預設被關掉了

在這裡可以教你怎麼把它打開

———————————-

而PHP & MySQL自己重頭裝到好的很多
市面上整合平台更多

Appserv、XAMPP、WAMP、MAMP…… 

對於裝在不同的系統(Win、Mac、Linux),路徑也會不致相同

但是有個好消息

phpMyAdmin對於平台的相依性很小
只要PHP和MySQL的環境有架起來
phpMyAdmin它,都能跑

如果你夠大膽,可以去官網下載最新版phpMyAdmin

http://www.phpmyadmin.net/home_page/index.php

 

然後換上去 (撰文的時候使用phpMyAdmin 3.5.1版)

———————————-

以我在使用的XAMPP為例

Windows 版的路徑:
C:\xampp\phpMyAdmin

Mac 版的路徑:
/Applications/XAMPP/xamppfiles/phpmyadmin

Linux 版的路徑:
/opt/lampp/phpmyadmin

 

Apache先關掉,
然後將舊版的phpMyAdmin備份起來(目錄更名),將新版3.5.1的phpMyAdmin複製上去(不要用取代的) 

———————————-

打開目錄底下的config.sample.inc.php,複製一份
檔名叫config.inc.php

使用文字編輯器打開

找到以下這一段:

/*
* phpMyAdmin configuration storage settings.
*/

/* User used to manipulate with storage */
// $cfg[‘Servers’][$i][‘controlhost’] = ”;
$cfg[‘Servers’][$i][‘controluser’] = ‘pma’;
$cfg[‘Servers’][$i][‘controlpass’] = ‘pmapass’;

/* Storage database and tables */
$cfg[‘Servers’][$i][‘pmadb’] = ‘phpmyadmin’;
$cfg[‘Servers’][$i][‘bookmarktable’] = ‘pma_bookmark’;
$cfg[‘Servers’][$i][‘relation’] = ‘pma_relation’;
$cfg[‘Servers’][$i][‘table_info’] = ‘pma_table_info’;
$cfg[‘Servers’][$i][‘table_coords’] = ‘pma_table_coords’;
$cfg[‘Servers’][$i][‘pdf_pages’] = ‘pma_pdf_pages’;
$cfg[‘Servers’][$i][‘column_info’] = ‘pma_column_info’;
$cfg[‘Servers’][$i][‘history’] = ‘pma_history’;
$cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma_table_uiprefs’;
$cfg[‘Servers’][$i][‘tracking’] = ‘pma_tracking’;
$cfg[‘Servers’][$i][‘designer_coords’] = ‘pma_designer_coords’;
$cfg[‘Servers’][$i][‘userconfig’] = ‘pma_userconfig’;
$cfg[‘Servers’][$i][‘recent’] = ‘pma_recent’;
$cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma_table_uiprefs’;

拿掉註解(不同版本,其中的值可能有多有少,會有些許不同,
找到你的那一段,不要直接複製,除非你很確定版本和我的相同),然後存檔

然後再打開Apache

———————————-

phpMyAdmin用MySQL的root帳號登入之後
點選匯入

檔案選擇 examples/create_tables.sql 的檔案,執行之後
會出現名字叫phpmyadmin的資料庫

然後按左上角的Exit鈕重新登入

就會選取資料庫時,就會看見Designer了

 

 

 

參考資料:

Enable Designer in PHPMyAdmin

http://www.novell.com/communities/node/8932/enable-designer-phpmyadmin

[Android] 使用HTTP的POST方式和網頁表單溝通 (加上資料庫、執行緒)

Screen Shot 2012-04-06 at 下午4.47.14     

 

這是由之前寫的這一篇

http://j796160836.pixnet.net/blog/post/28994669

所延伸出來的

 

眼尖的網友已經發現,之前放上的程式碼範例已經不能Run了
把專案使用的Android版本放在2.3.3以下就可以正確執行
而把它升到4.0就會出錯

有人發現為什麼了嗎?


打開LogCat就可以清楚的看到

Screen Shot 2012-04-06 at 上午12.13.33  

Android 4.0 (ICS)在網路的部份多了一個新的Exception

叫做android.os.NetworkOnMainThreadException
意思很白話的就是:網路的活動跑在主要執行緒上了啦!

ICS很貼心的告訴你,這樣子你的APP可能會因為等待回應太久(超過5秒)
而會被系統強制關閉(收到ANR)

 

(備註:之前是為了示例方便,所以沒有照多執行緒的寫法撰寫,在這裡當然也就不能執行啦
Android光這點就還蠻嚴謹的)


OK,瞭解為何出錯的原因
也剛好在這裡,帶大家看看多執行緒要怎麼改吧

專案的Layout版面等定義上和之前這篇一模一樣
有特別修改的地方會特別標出

 

package com.J_Test.httpPostTest;

import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; 

public class Main extends Activity implements OnClickListener

{

   private EditText txtMessage;

   private Button sendBtn;

   private String uriAPI = "http://192.168.1.3/httptest/httpPostTest.php";

   /* 「要更新版面」的訊息代碼 /

   protected static final int REFRESH_DATA = 0x00000001;

 

   /* 建立UI Thread使用的Handler,來接收其他Thread來的訊息 /

   Handler mHandler = new Handler()

   {

      @Override

      public void handleMessage(Message msg)

      {

          switch (msg.what)

          {

          // 顯示網路上抓取的資料

          case REFRESH_DATA:

             String result = null;

             if (msg.obj instanceof String)

                result = (String) msg.obj;

             if (result != null)

                // 印出網路回傳的文字

                Toast.makeText(Main.this, result, Toast.LENGTH_LONG).show();

             break;

          }

      }

   };

 

   @Override

   public void onCreate(Bundle savedInstanceState)

   {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);

 

      txtMessage = (EditText) findViewById(R.id.txt_message);
      sendBtn = (Button) findViewById(R.id.send_btn);

 

      if (sendBtn != null)
          sendBtn.setOnClickListener(this);

   }

 

   @Override
   public void onClick(View v)

   {

      if (v == sendBtn)

      {

          if (txtMessage != null)

          {

             // 擷取文字框上的文字

             String msg = txtMessage.getEditableText().toString();

             // 動一個Thread(執行緒),將要傳送的資料放進Runnable中,讓Thread執行

             Thread t = new Thread(new sendPostRunnable(msg));

             t.start();

          }

      }

   }

 

   private String sendPostDataToInternet(String strTxt)

   {

      / 建立HTTP Post連線 /

      HttpPost httpRequest = new HttpPost(uriAPI);

      /*

       * Post運作傳送變數必須用NameValuePair[]陣列儲存

       */

      List<NameValuePair> params = new ArrayList<NameValuePair>();

      params.add(new BasicNameValuePair("data", strTxt));

 

      try

      {

          / 發出HTTP request /

          httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

          / 取得HTTP response /

          HttpResponse httpResponse = new DefaultHttpClient()

                .execute(httpRequest);

          / 若狀態碼為200 ok /

          if (httpResponse.getStatusLine().getStatusCode() == 200)

          {

             / 取出回應字串 /

             String strResult = EntityUtils.toString(httpResponse

                   .getEntity());

             // 回傳回應字串

             return strResult;

          }

      } catch (Exception e)

      {

          e.printStackTrace();

      }

      return null;

   }

 

   class sendPostRunnable implements Runnable

   {

      String strTxt = null;

 

      // 建構子,設定要傳的字串

      public sendPostRunnable(String strTxt)

      {

         this.strTxt = strTxt;

      }

 

      @Override

      public void run()

      {

          String result = sendPostDataToInternet(strTxt);

          mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget();

      }

   }

}


特別注意這裡

  Handler mHandler = new Handler()

   {

      @Override

      public void handleMessage(Message msg)

      {

          switch (msg.what)

          {

          case REFRESH_DATA:

             // …………(相關程式碼)

             break;

          }

      }

   }; 

這是Android對於多執行緒的寫法

這裡做了一個Handler來接收訊息

因為當你建立執行緒,資料處理與主執行緒無關

當然,新建出來的執行緒,是碰不到UI介面的 (會跳Exception)

所以才會如此設計

 

訊息,說穿了就是一個int,可以自行定義訊息的內容

 

/** 「要更新版面」的訊息代碼 */

   protected static final intREFRESH_DATA = 0x00000001;

 

類別一開始就定義這個常數

然後在

public void handleMessage(Message msg){

}

的地方就可以使用 msg.what 存取到訊息的內容

這裡用Switch – case的方式撰寫

 


 

發訊息的函式如下

mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget(); 

發訊息的相關方法呼叫可參考官方說明

http://developer.android.com/reference/android/os/Handler.html

 

文件上可看到,obtainMessage有這幾個多載方法

obtainMessage(int what);

obtainMessage(int what, int arg1, int arg2);

obtainMessage(int what, int arg1, int arg2, Object obj);

obtainMessage(int what, Object obj);

常用的有第一、第二、第四種

 

尤其是第四種,這訊息可以傳入Object

所以自由度很高

 


最後,是建立執行緒

 

// 動一個Thread(執行緒),將要傳送的資料放進Runnable中,讓Thread執行

Thread t = new Thread(new sendPostRunnable(msg));

t.start();

 

這裡是用一個臨時的執行緒的方式

在建構子之中傳入一個Runnable來達成

執行緒的部分也可以用匿名class的方式撰寫

 

// 擷取文字框上的文字

final String msg = txtMessage.getEditableText().toString();

new Thread()

{

       public void run()

       {

            String result = sendPostDataToInternet(msg);

            mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget();

       }

}.start();

 

但這樣的方式要注意,內部類別(Inner class)當中

只能存取外部的常數(這是Java的規定)

final String msg;

所以為何String前面要加上final了

 

詳細多執行緒可參考

[Android] 多執行緒-Handler和Thread的關係

http://j796160836.pixnet.net/blog/post/28766165

[Android] 關於Thread執行緒

http://j796160836.pixnet.net/blog/post/29895257

 


很多網友都問到,

為何我在Android傳送出來的資料
在瀏覽器中怎麼都看不見

因為資料到伺服器上沒有將它存下來
在這裡可以做一些修改

我們把傳到伺服器上的資料
用MySQL存下來,然後再顯示最後輸入的資料

 

以PHP為例,我們在phpmyadmin上
建立一個資料庫,名稱叫 httpPostTest

實際設定如圖:

Screen Shot 2012-04-06 at 下午2.45.22  

這是其對應的SQL

CREATE TABLE IF NOT EXISTS weblog (
log_id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘編號’,
data varchar(255) NOT NULL COMMENT ‘傳入的資料’,
post_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘發佈時間’,
PRIMARY KEY (log_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT=’訊息記錄’ AUTO_INCREMENT=1 ;

 


 

之前使用的 httpPostTest.php 我們做一些修改

<?php

// 資料庫相關資料
$database_dblink = "httpPostTest";
$username_dblink = "root";
$password_dblink = "YOUR_ROOT_PASSWORD";

// 建立資料庫連線
$dblink = mysql_pconnect("localhost", $username_dblink, $password_dblink) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_query("SET NAMES utf8",$dblink);
mysql_query("SET CHARACTER_SET_CLIENT=utf8",$dblink);
mysql_query("SET CHARACTER_SET_RESULTS=utf8",$dblink);
mysql_select_db($database_dblink, $dblink);

// 宣告utf-8的編碼
header("Content-Type:text/html; charset=utf-8");
// 接收POST/GET的資料
$data=@$_REQUEST[‘data’];

// 如果有資料
if (strcmp(trim($data), "")!=0)
{
      // 將資料輸入進資料庫
      $insertSQL = sprintf("INSERT INTO weblog (data) VALUES (‘%s’);", $data);
      mysql_query($insertSQL, $dblink) or die(mysql_error());
}

// 從資料庫撈出來最後一筆資料
$query_rs = "SELECT * FROM weblog order by log_id desc limit 0,1";
$rs = mysql_query($query_rs, $dblink) or die(mysql_error());

$row = mysql_fetch_assoc($rs);
echo "data=".$row[‘data’]."n"."time=".$row[‘post_time’];

?>

這樣在瀏覽器就會暫存最後一筆的資料了

如果有學過PHP相關的語法

以上的程式碼應該不難才是

 

 


最後還是提醒一下,Android還沒有跑出來的朋友
若是在Logcat看到類似Permission denied的字眼

代表你忘記了AndroidManifest.xml的這句摟,詳細看之前寫的這篇

    <!– 這裡加入可以存取網路的權限 –>

    <uses-permission android:name="android.permission.INTERNET" />

 


關於source code的部份,我已經放上gitHub了

https://github.com/j796160836/httpPostTest

[iOS筆記] 關於Protocol和物件導向 (Java下的介面(Interface) )

有關於iOS底下的Protocol

 

請參照至其版大的文章

Protocol in Objective-C

http://blog.eddie.com.tw/2010/12/11/protocol-in-objective-c/

這版大實在寫的思路很清晰,推薦一下摟

(看來我還是要多多拜讀別人的文章才是)

————————————————————————————————

為了響應不全文引用,以下採用節錄的,完整內容請移至版大的文章

 

Objective-C是單一繼承的,如果想要做到一個類別同時擁有多種型別的能力,可以透過實作其它型別的interface來達成這個目的。在Java/AS3是用”interface”這個關鍵字,在Objective-C則是用”@protocol”。

(有寫過Java/AS3的要特別注意不要把interface跟protocol搞混了
,在Objective-C的interface等於Java/AS3的class,而protocol則是相當於interface)

Johnny: 關於protocol這點,我也常常搞混…..= =||


如果你要新增一個自定的protocol的話,可以直接在你的專案裡新增一個protocol檔:

image

新增完成之後(它是一個header檔),就可以開始來寫了,

—————————————————————————————————

程式碼如下:

@protocol Drawable

@required
-(void) draw;
-(void) changeColor;

@optional
-(void) whateverMethod;

@end

在上面這段程式碼裡,我放了三個方法,但沒有寫內容。接下來如果我要實作自這個protocol的話,所有定義在@protocol裡的方法都得實作出來。

如果沒特別標明的,預設是@required。如果你要實作這個protocol的話,照英文字面來看,@required的部份是規定要實作的,@optional的話就隨你高興了。要注意的是@required跟@optional這兩個語法的影響範圍,是從它以下所有的method都會被影響,直到另一個directive或是@end為止


————————————————————————————————————————-

實作protocol的方法就是用”<>”標記,裡面放protocol的名稱。並不限定只能實作一個protocol,如果要實作多個protocol的話,則是用逗點分開

因為在protocol的地方已經有定義好了方法,所以在@interface的地方就不用再特別寫一次,只要在@implementation裡補上該實作的方法就行了。

// ————–

// interface
// ————–
#import <Cocoa/Cocoa.h>
#import “Drawable.h”

@interface Book : NSObject <Drawable>
{
int price;
}
@property int price;

@end

// ————–
// implementation
// ————–
#import “Book.h”
@implementation Book

@synthesize price;

// 實作方法draw
-(void) draw
{
NSLog(@”draw me!”);
}

// 實作方法changeColor
-(void) changeColor
{
NSLog(@”change color!”);
}

@end

 

————————————————————————————————————————-

Johnny: 簡單來講,protocol就是Java裡的介面(Interface),上面開出來的方法(method)
且有@required字樣的都要被實作(implementation)

protocol名稱加綴在類別(class)後面
只是為了要讓Complier,確實的去檢查,開出來的方法

是有都通通有實作完畢

實驗發現,某些Class對於protocol要求沒那麼嚴苛

只要實作出它要的方法,而不用加掛這個綴字

而且避免混淆,我現在習慣通通都加上去

(包含放在Class名稱之後的 < > ,和其protocol要的方法一起宣告在header檔)

 

 

我還是覺得還是要學Java一樣,嚴謹一點比較好,較不會出錯