根據上述, 解決方案其實很簡單, 就是自己實作一個只會傳回 1 與 -1 的比較器, 在建構 SortedList 時傳入, 這樣即使 key 相同也可以存入。比較器的實作非常簡單, 可參考這一篇討論串中一樓的解答:
class MyComparer : IComparer
{
public int Compare(int x, int y)
{
if (x < y)
return -1;
else return 1;
}
}
非常簡單。class MyComparer : IComparer
{
public int Compare(int x, int y)
{
if (x < y)
return -1;
else return 1;
}
}
非常簡單。#ifndef IBOutlet
#define IBOutlet
#endif
#ifndef IBAction從定義可以看出來, IBOutlet 與 IBAction 對於程式碼沒有實質的意義, 存在的作用只是像是標籤一樣, 標示了程式碼中的某個屬性可以用來對應到介面上的某個同樣類別的元件, 或是某個方法可以用來回應規格相符的事件。
#define IBAction void
#endif
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@synthesize myLabel;
@synthesize myLabel = _myLabel;也就是將對應的成員變數以你指定的屬性名稱加上 "_" 為字首命名, 使得屬性名稱與對應的成員變數名稱變成不一樣了, 因此無法以 myLabel 操作元件, 而必須加上 self 以 self.myLabel 才能操作對應的元件。當然, 也可以直接使用變數, 但這樣除了違背封裝的意圖, 也會使用到程式中沒有出現過得變數。這下子, 書中原本的程式以及解說的內容都得一併修改, 真是麻煩了。
事實證明, 這樣的確是可以運作, 連個編譯的錯誤訊息都沒有。當使用者點選了 UIAlertView 上的按鈕時, 的確會引發 clickedButtonAtIndex。@interface ViewController : UIViewController
....
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
.....
}
@end
實在覺得很奇怪, 兩個元件的 pattern 其實是一樣的, 但為甚麼一個需要明確標示遵守協定, 另一個卻不用?經過 google 找到這一篇 Why do I not need to declare UIAlertViewDelegate in the header?, 看起來原因有兩個:@interface ViewController :
UIViewController<UIActionSheetDelegate>
.....
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
.....
}
@end
respondsToSelector:@selector(delegatedMethod:)
檢查委派物件是否具有指定的方法, 才會實際叫用該方法, 而不是依靠是否遵循特定的協定來判斷。eclipse.exe -vmargs -Duser.language=en”為了方便起見, 你可以建立不同的捷徑, 在不同語系之間轉換。不過實際上會想換回英文, 大概也都不需要在不同語系間切換了, 這時可以把上述的參數加到在 Eclipse 資料夾下的 eclipse.ini 檔案中, 例如:
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
...............................
-vmargs這樣執行 eclipse 時就會強制改用英文語系了。
-Dosgi.requiredJavaVersion=1.5
-Dhelp.lucene.tokenizer=standard
-Xms40m
-Xmx384m
-Duser.language=en”
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1"> <title>jQuery Mobile Demo</title> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script type="text/javascript"> $(document).bind("mobileinit", function(){ $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false }); }); </script> <script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script> </head> <body> <div data-role="page"> <div data-role="header" data-position="fixed" data-fullscreen="true"> <h1>全螢幕標頭</h1> </div> <div data-role="content"> <img src="mycat.jpg" /> </div> </div> </body> </html>這個程式是希望能在初始化的階段透過第 11 行的程式設定固定在頁首與頁尾的工具列不會因為使用者碰觸畫面而自動隱藏或重現, 不過實際執行之後, 發現設定失效, 工具列還是會以預設的方式自動隱藏或重現。經過查詢 jQuery Mobile 文件以及 Google 爬文後, 發現 mobileinit 事件發生時, 其實後續的 HTML 內容並未載入, 因此事件處理方法中的 $("[data-role=header],[data-role=footer]") 根本就抓不到元素, 自然無法讓期望的設定生效。為了解決這個問題, 只要改成處理 pageinit 事件, 也就是在後續的 HTML 內容生成後再進行設定, 就可以正確執行了。修改的程式如下:
$(document).bind("pageinit", function(){ $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false }); });你也可以在事件處理的程式中多加上一行 alert() 呼叫, 就可以觀察實際抓取到的元素內容了:
$(document).bind("pageinit", function(){ $("[data-role=header],[data-role=footer]").fixedtoolbar({ tapToggle:false }); alert($("[data-role=header],[data-role=footer]").text()); });