2012年11月26日 星期一

Stanford iOS 開發課程 (CS193P) 教科書

最受歡迎的 Stanford iOS 開發課程 (CS193P) 教科書, 包含 Xcode 4.5 和 iOS 6。目前全球50國家免費下載。

iPad and iPhone App Development 教科書

MapReduce Design Patterns


  • Summarization patterns: get a top-level view by summarizing and grouping data
  • Filtering patterns: view data subsets such as records generated from one user
  • Data organization patterns: reorganize data to work with other systems, or to make MapReduce analysis easier
  • Join patterns: analyze different datasets together to discover interesting relationships
  • Metapatterns: piece together several patterns to solve multi-stage problems, or to perform several analytics in the same job
  • Input and output patterns: customize the way you use Hadoop to load or store data


2012年11月24日 星期六

Singleton Pattern

SingletonObject.h
#import <Foundation/Foundation.h>
@interface SingletonObject : NSObject {
@private
int count;
}

//統一透過此函式來使用 Singleton 物件的方法
+ (SingletonObject *)sharedSingletonObject;
//增加
- (void)addCount;
//呈現
- (void)showCount;
@end


  1. #import "SingletonObject.h"
  2.  
  3. @implementation SingletonObject
  4.  
  5. //宣告一個靜態的Singleton物件
  6. static SingletonObject *_singletonObject = nil;
  7.  
  8. - (id)init {
  9. self = [super init];
  10. if (self) {
  11.  
  12. //將 count 初始化為0
  13. count = 0;
  14. }
  15.  
  16. return self;
  17. }
  18.  
  19. //執行時會判斷是否 _singletonObject 已經完成記憶體配置
  20. + (SingletonObject *)sharedSingletonObject {
  21.  
  22. @synchronized([SingletonObject class]) {
  23.  
  24. //判斷_singletonObject是否完成記憶體配置
  25. if (!_singletonObject)
  26. [[self alloc] init];
  27.  
  28. return _singletonObject;
  29. }
  30.  
  31. return nil;
  32. }
  33.  
  34. + (id)alloc {
  35. @synchronized([SingletonObject class]) {
  36.  
  37. //避免 [SingletonObject alloc] 方法被濫用
  38. NSAssert(_singletonObject == nil, @"_singletonObject 已經做過記憶體配置");
  39. _singletonObject = [super alloc];
  40.  
  41. return _singletonObject;
  42. }
  43.  
  44. return nil;
  45. }
  46.  
  47. - (void)addCount {
  48. count += 1;
  49. }
  50.  
  51. - (void)showCount {
  52. NSLog(@"%d", count);
  53. }
  54.  
  55. - (void)dealloc {
  56. [super dealloc];
  57. }
  58.  
  59. @end

NSString 物件的操作方法

宣告與格式化
//建立字串物件
NSString *str = @"NSString";
//建立空字串
NSString *str =[[NSString alloc] init];
//與CString的轉換
char *cstring = "CString";
NSString *str = [[NSString alloc] initWithCString:cstring];
//字串格重新式化
NSString *str =[[NSString alloc] initWithString:@"NSString"];
str = [NSString stringWithFormat:@"This is %@", str];
NSLog(@"%@", str);


大小寫的轉換
//字串的大小寫轉換
NSString *str =[[NSString alloc] initWithString:@"NSString"];
//全部大寫
NSLog(@"%@",[str uppercaseString]);
//全部小寫
NSLog(@"%@",[str lowercaseString]);
//字首大寫
NSLog(@"%@", [str capitalizedString]);


在 iOS 6 SDK 中使用新的方法函式加入了 NSLocale 的概念,使裝置在不同的語系設定下皆可以正確的轉換這些字串。
//全部大寫
NSString *upperString = [string uppercaseStringWithLocale:[NSLocale currentLocale]];
NSLog(@"全部大寫: %@", upperString);
//全部小寫
NSString *lowerString = [string lowercaseStringWithLocale:[NSLocale currentLocale]];
NSLog(@"全部小寫: %@", lowerString);
//只有字首大寫
NSString *capString = [string capitalizedStringWithLocale:[NSLocale currentLocale]];
NSLog(@"只有字首大寫: %@", capString)


比較
//字串比較
NSString *str_A =[[NSString alloc] initWithString:@"NSString"];
NSString *str_B =[[NSString alloc] initWithString:@"nsstring"];
BOOL compare;

//字串區分大小寫比較
compare = [str_A isEqualToString:str_B];

//字串不區分大小寫比較
compare = [str_A caseInsensitiveCompare:str_B] == NSOrderedSame;


排序

NSString *string = @"0";
NSComparisonResult result = [string caseInsensitiveCompare:@"A"];

switch (result) {
case NSOrderedAscending:
NSLog(@"升冪");
break;

case NSOrderedSame:
NSLog(@"忽略大小寫相同的字串");
break;

case NSOrderedDescending:
NSLog(@"降冪");
break;

default:
NSLog(@"無法判定");
break;
}

在 Objective-C 中 NSComparisonResult 的定義。
enum _NSComparisonResult {NSOrderedAscending = -1, NSOrderedSame, NSOrderedDescending};
typedef NSInteger NSComparisonResult;


搜尋
//搜尋字串
NSString *str =[[NSString alloc] initWithString:@"NSString"];
//有區分大小寫
NSRange search = [str rangeOfString:@"Str"];
//數字表示第幾字元開始有符合(從0開始)
NSLog(@"%i", search.location);


擷取
//字串擷取
NSString *str =[[NSString alloc] initWithString:@"NSString"];

//擷取前五位元
NSLog(@"%@", [str substringToIndex:5]);

//擷取時略過前五位元
NSLog(@"%@", [str substringFromIndex:5]);

//從第二個位元開始擷取三個位元(第一個字符為第零位元)
NSLog(@"%@", [str substringWithRange:NSMakeRange(2, 3)]);


替換
//字串替換
NSString *str =[[NSString alloc] initWithString:@"NSString"];
NSString *_str;

//尋找字串並取代
_str = [str stringByReplacingOccurrencesOfString:@"NS" withString:@"CS"];
NSLog(@"%@", _str);

//尋找範圍並取代
_str = [str stringByReplacingCharactersInRange:NSMakeRange(2, 3) withString:@"*******"];
NSLog(@"%@", _str);


如何拆解 NSString 並置入 NSArray 中。
NSString *string = @"Never Forget Me";
//字串以空白間鍵做分段依據
NSArray *strArray = [string componentsSeparatedByString:@" "];

2012年11月20日 星期二

XCode 常用快捷鍵

(4.3.2環境下)

⌘——Command ()

⌃ ——Control

⌥——Option (alt)

⇧——Shift

⇪——Caps Lock

fn——功能鍵就是fn

自動排版 ^ + i(針對當前行,如果想全文,先全選,再剪切,再粘貼就可以哦)

代碼摺疊 ⌘ + ⌥ + left(or right)

註釋代碼 ⌘ + /

查看名稱定義,進入頭文件 ⌘+鼠標左鍵

查看名稱api文檔 ⌥+鼠標左鍵,非常方便哦

前進後退文本文件 ⌘+⌃ +←or→

關閉當前文本文件 ⌘+⌃+w

增加縮進 ⌘ + [ ( 『 ] 』 是減少)

打開查找窗口 ⌘ + shift + F

iOS 6版本與之前版本差異

1、4英寸屏幕

舊的應用程式要與4英寸屏幕進行匹配,需要準備一張Default-568h@2x.png圖片,系統根據是否有此資源來識別是否支持4英寸屏幕。

至於其他資源不允許使用xxx-568h.jpg此格式來匹配屏幕,需要使用程式碼對屏幕進行檢測來分別進行匹配。

2、UINavigationViewController的變化

該類的initWithRootViewController在之前的版本是最終會使用到 init 方法的。因此在繼承UINavigationViewController時,直接在重寫 init 方法來初始化物件所需屬性即可。

但是在iOS6上是不會使用init方法,因此需要注意。

3、CFRelease的變化

在之前版本中如果CFRelease傳入 nil 是被允許的,這也符合我們傳入 nil 物件不會對我們的程序造成影響,

但是在iOS6中,這樣的寫法直接就當機了,所以程式碼中還是需要判斷一下是否為 nil 才是安全的做法。

4、UIPickerView的變化

在之前版本中可以使用
[_pickerView selectRow:-1 inComponent:0 animated:YES]; 。

但在iOS6中會導致當機。

5、UIActivityIndi​​catorView的變化

在之前的版本中假如調用了startAnimating方法之後,只要把UIActivityIndi​​catorView添加到子視圖中就會顯示加載動畫,

但在iOS6中只要移出顯示隊列則會停止動畫,特別在UITableViewCell中加入此控件,只要滾動幾下Cell的UIActivityIndi​​catorView就消失了,為解決此問題可以在加入顯示隊列時根據isAnimating屬性來判斷是否執行動畫,如果沒有則重新調用一下startAnimating方法。

6、通訊錄列表獲取差異

自iOS6.0後獲取通訊錄列表需要詢問用戶,經過用戶同意後才可以獲取通訊錄用戶列表。

而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函數轉變為ABAddressBookCreateWithOptions函數。

下面程式碼是獲取通訊錄用戶列表的方法,相容之前的版本。
ABAddressBookRef addressBook = nil;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0)
{
addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
//等待同意後向下執行
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
{
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
} else {
addressBook = ABAddressBookCreate();
}
NSArray *personArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);



2012年11月19日 星期一

NSAssert

可以透過設定 Target 的 Build Settings 來防止編譯器將斷言的程式碼組譯到你的程式裡,在 Build Settings 中找到 Apple LLVM compiler 3.0 - Preprocessing 項目(Xcode 4.2),將 Preprocessor 的 Release 新增一個 NS_BLOCK_ASSERTIONS 值即可,之後當你使用 Release 版本進行編譯時程式將不會觸發任何的 assert。
 如果你想要在程式暫停時標示斷言的該行程式碼,可以案專案中的 Breakpoint Navigator 點選「+」新增一個 Symbolic Breakpoint,並在 Symbol 設定 objc_exception_throw,之後將此 Symbolic Breakpoint 設定到 要作用的區域裡即可。



按下專案上的中斷點按鈕

取得世界各地時間

//取得目前已知的所有地理名稱
NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];

//取得本地目前時間
NSDate *date = [NSDate date];

for(NSString *name in timeZoneNames) {
NSTimeZone *timezone = [[NSTimeZone alloc] initWithName:name];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

//設定時間格式
[formatter setDateFormat:@"YYYY-MM-d HH:mm:ss"];

//設定時區
[formatter setTimeZone:timezone];

//時間格式正規化並做時區校正
NSString *correctDate = [formatter stringFromDate:date];

NSLog(@"地點:%@ 當地時間:%@",[timezone name], correctDate);

[formatter release];
[timezone release];
}

Observer Pattern -- NSNotificationCenter

NSNotificationCenter 可以分成三部份來看,分別是註冊(訂閱)、註銷(取消訂閱)與訊息通知。
- (id)init {
self = [super init];
if (self) {

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(echoNotification:) name:@"showSomething" object:nil];
}

return self;
}

只要有 NSNotificationCenter 發佈有關 showSomething 訊息事件的通知,此物件就會執行 echoNotification: 函式。
- (void)echoNotification:(NSNotification *)notification {

//取得由NSNotificationCenter送來的訊息, 假設為 NSArray 形態的參數。
NSArray *anyArray = [notification object];

NSLog(@"%@", [anyArray componentsJoinedByString:@"\n"]);
}

取消訂閱
[[NSNotificationCenter defaultCenter] removeObserver:self];

對特定的訊息事件取消訂閱
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"showSomething" object:nil];

訊息通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"showSomething" object:stringArray];

#pragma mark Preprocessor

可以單純使用下列指令來製作沒有標籤的分隔線。
#pragma mark -

不僅如此,我們還能用MARK:、TODO:、FIXME:、!!!:、???:作更進一步的劃分,譬如說:
#pragma mark - Something Stupid
// MARK: markmarkmark
// TODO: todotodotodo
-(void)stupidA
{
}
// FIXME: fixmefixmefixme
-(void)stupidB
{
}
#pragma mark Something Smart
// ???: ?????????
-(void)smartA
{
}
/// !!!: !!!!!!!!!
-(void)smartB
{
}

Nil, nil, NULL

nil 代表一個類別個體,而個體的指標指向 Empty,而 Nil 則是用來區別所指向的對象是一個類別 Class 而非個體,NULL 則指的是任何指向空值的指標(我們姑且可以想成當作一個數值來使用)。
#define Nil __DARWIN_NULL /* id of Nil class */
#define nil __DARWIN_NULL /* id of Nil instance */

#define __DARWIN_NULL ((void *)0)

#define NULL ((void*)0)

例如想直接透過程式碼來呼叫按紐事件,由於並沒有經由按鈕來觸發,因此必須將輸入的參數設為空值。
- (IBAction)onButton:(id)sender {
NSLog(@"hi");
}

[self onButton:nil];

關閉專案 ARC

XCode 多了一個 ARC 的新編譯器特性,在使用模板創建一個專案的時候會自動啟用這個特性( -fobjc-arc)。

可以在 Build Setting => "Apple LLVM compiler 3.0-Auto Reference Counting「 => "Migrate code from MRR to ARC" 設置為 "MIGRATE code to ARC after building with PRECHECK" ,這個就可以跳過煩人的預語法檢查報錯,且自動轉換成ARC。

關閉專案 ARC 機制的方法只要到專案下的 Build Setting => Apple LLVM compiler 3.0-Code Generation => Objective-C automatic Reference Counting" 項目,設定為NO即可。


使用ARC機制的寫法
@property (weak, nonatomic) IBOutlet UIButton *button;

未使用ARC機制的寫法
@property (retain, nonatomic) IBOutlet UIButton *button;

//使用ARC機制時並不會產生此函式
- (void)dealloc {
//釋放資源
}


如果只是想要關掉專案內特定幾的檔案的 ARC 機制,就可以採用 Flag 旗標設定的方式,首先找到專案 Targes 下的 Build Phase 將 Compile Source 項目展開,點選想要停用 ARC 機制的檔案並按下 ENTER,加入 -fno-objc-arc 的旗標設定,就可以停用特定檔案的 ARC 機制。

2012年11月17日 星期六

表達式封裝特性,@( expression )

表達式封裝特性,@( expression ),比如
NSString *name = @([self getMyName]);
數組可以這麼寫:
NSArray *array = @[@"1", @"2"];
NSString *str = array[0];
NSMutable *mutableArray = [@[@"1"] mutableCopy];

字典可以這麼寫:
NSDictionary *dict = @{@"name" : @"Jason", @"password" : @"Hello,world"};
NSString *name = dict[@"name"];

當寫下這一行程式
// when you write this:
dict = @{ k1 : o1, k2 : o2, k3 : o3 };

新的編譯器為我們做了些事情(代碼片段摘自WWDC 2012 Session 405):
// compiler generates:
id objects[] = { o1, o2, o3 };
id keys[] = { k1, k2, k3 };
NSUInteger count = sizeof(objects) / sizeof(id);

dict = [NSDictionarydictionaryWithObjects: objects
forKeys: keys
count: count];

神奇的@符號簡化語法

以前字符串可以這麼寫:
NSString *str = @"Hello";。

現在NSNumber也可以這麼寫:
NSNumber *number = @'H';
number = @1.2;
number = @YES;
number = @(60 * 60 * 24);

如果寫了這一行程式
id x = @42;

結果看到以下報錯
lit.m:3:8: error: initializer element is not a compile- time constant
id x = @42;
^~~

這到底是為什麼?因為對於整數是不能像字符串那樣處理的;這只是個讓程序員方便的語法而已,能讓我們創建一個autoreleased 的NSNumber物件。在Objective-C 11中,如果你定義下面這樣的macro,代碼如下:
#define N(x) _Generic((x), \
int : [NSNumber numberWithInt: x], \
float : [NSNumber numberWithFloat: x], \
double : [NSNumber numberWithDouble: x])

這個例子接受一個數值參數然後返回一個NSNumber的物件,以下的代碼都是等價的
x = N(12);
x = @12;

x = N(42.5);
x = @42.5;
x = N(42.5f);
x = @42.5f;

同理你也可以為long, longS以及long doubleS等等來擴展這樣的macro。甚至是更加複雜的數據。

自動合成屬性

在XCode 4.2之前的版本,我們在.h文件裡宣告屬性@property後,還需要在.m文件中合成@synthesize,很麻煩。

現在,我們只需要宣告 @property name 即可,Xcode會自動合成 @synthesize name = _name。
@property (attribute1, attribute2) propertyName;

與所有權有關係的屬性,關鍵字間的對應關係。
屬性值關鍵字所有權說明
strong __strong add reference to keep object alive
weak __weak object can disappear, become nil
unsafe_unretained __unsafe_unretained
copy __strong make copy on assign
assign __unsafe_unretained normal assign, no reference
retain __strong


nonatomic : make not hreadsafe, increase perf


strong
該屬性值對應 __strong 關鍵字,即該屬性所宣告的變量將成為物件的持有者。

weak
該屬性對應 __weak 關鍵字,與 __weak 定義的變量一致,該屬性所宣告的變量將沒有物件的所有權,並且當物件被破棄之後,物件將被自動賦值nil。

並且,delegate 和 Outlet 應該用 weak 屬性來聲明。同時,如上一回介紹的 iOS 5 之前的版本是沒有 __weak 關鍵字的,所以 weak 屬性是不能使用的。這種情況我們使用 unsafe_unretained。

unsafe_unretained 等效於__unsafe_unretaind 關鍵字宣告的變量;像上面說明的,iOS 5之前的系統用該屬性代替 weak 來使用。

copy
與 strong 的區別是宣告變量是拷貝物件的持有者。

assign
一般Scalar Varible用該屬性宣告,比如,int, BOOL。

retain
該屬性與 strong 一致;只是可讀性更強一些。

讀寫相關的屬性 (readwrite, readonly)

readwrite : create getter & setter (default)
readonly : create getter only

讀寫相關的屬性有 readwrite 和 readonly 兩種,如果使用ARC之後,我麼需要注意一下 readonly 屬性的使用。

比如下面的變量宣告。
@property (nonatomic, readonly) NSString *name;

一般宣告為 readonly 的變量照理說應該不需要持有所有權了,但是在ARC有效的情況下,將出現下面的錯誤信息 :
「ARC forbids synthesizing a property of an Objective-C object with unspecified ownership or storage attribute」
如果定義了ARC 有效,那麼必須要有所有者屬性的定義;所以我們的程式碼要改成這樣
@property (nonatomic, strong, readonly) NSString *name;

不過有一點,Scalar Variable 的變量都有 assign 的屬性定義,所以不需要給他們單獨的宣告。

iBooks Author 2.0開始支持 LaTeX 和 MathML

相信常和科技論文排版打交道的人對 LaTex 文檔排版系統不會感到陌生,為了更好的佔據教科書市場,蘋果最新更新的 iBooks Author 開始對LaTex以及MathML(另一種教科書常用的數學方程式及公司標記語言)提供支持。

也就是說,那些早已熟悉這類標記語的教育專家、數學家以及學生們可以輕鬆的通過iBooks Author 完成材料的編寫。而另一方面,對於希望在教育領域,尤其是教科書領域,有所建樹的蘋果來說,在軟件上滿足並迎合潛在的教育用戶們的需求無疑能在硬件上帶來更多的收穫。

2012年11月16日 星期五

蘋果2012第三季度財報總結

蘋果2012第三季度財報總結,iOS設備確實是蘋果的主要收入來源。



收入

iPhone:46%
iPad:26%
iPod:3%

iOS設備收入佔了公司總收入的75%。

OSX設備僅佔14%,不過是iOS設備的1/5。

自定義 iOS UI 的案例

iOS UI Patterns 網站:

http://pttrns.com/

iOS 6 韌體

iOS 6 直接下載韌體更新,位置如下:

iPad Wi-Fi (3rd generation)
http://appldnld.apple.com/iOS6/Restore/041-3515.20120919.OYzOG/iPad3,1_6.0_10A403_Restore.ipsw

iPad Wi-Fi + Cellular (model for ATT)
http://appldnld.apple.com/iOS6/Restore/041-7163.20120919.19UEI/iPad3,3_6.0_10A403_Restore.ipsw

iPad Wi-Fi + Cellular (model for Verizon)
http://appldnld.apple.com/iOS6/Restore/041-7161.20120919.5CyjO/iPad3,2_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi (Rev A)
http://appldnld.apple.com/iOS6/Restore/041-2187.20120919.vmGkW/iPad2,4_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi
http://appldnld.apple.com/iOS6/Restore/041-0804.20120919.9SgHU/iPad2,1_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi + 3G (GSM)
http://appldnld.apple.com/iOS6/Restore/041-7165.20120919.eZTyh/iPad2,2_6.0_10A403_Restore.ipsw

iPad 2 Wi-Fi + 3G (CDMA)
http://appldnld.apple.com/iOS6/Restore/041-7167.20120919.y2ard/iPad2,3_6.0_10A403_Restore.ipsw

iPhone 4S
http://appldnld.apple.com/iOS6/Restore/041-7181.20120919.lEuOK/iPhone4,1_6.0_10A403_Restore.ipsw

iPhone 4 (GSM)
http://appldnld.apple.com/iOS6/Restore/041-7175.20120919.wvv7Y/iPhone3,1_6.0_10A403_Restore.ipsw

iPhone 4 (CDMA)
http://appldnld.apple.com/iOS6/Restore/041-7179.20120919.bDw4g/iPhone3,3_6.0_10A403_Restore.ipsw

iPhone 3GS
http://appldnld.apple.com/iOS6/Restore/041-7173.20120919.sDDMh/iPhone2,1_6.0_10A403_Restore.ipsw

iPod touch (4th generation)
http://appldnld.apple.com/iOS6/Restore/041-0807.20120919.soT6X/iPod4,1_6.0_10A403_Restore.ipsw

2012年10月24日 星期三

iBooks 3 和 iBook Author 2.0 同步更新

在 Apple 產品發表會上,Apple 除更新了旗下一系列產品線外,亦為使用者和內容開發者分別推出 iBooks 3 和 iBook Author 2.0,即日起已可在 App Store 和 Mac Store 免費下載。

iBooks 3 的新功能包括,從 iOS 6 的書架上可透過 iCloud 檢視你所有從 iBookstore 購買的書籍、使用新的「捲視」主題後可以手指在書籍中垂直捲視、接收已購書籍的更新內容 (包含新的章節、修正內容和其他改進項目)、在 iOS 6 環境下可查詢德文、西班牙文、法文、日文和簡體中文的單字定義、在 Facebook、Twitter、訊息或郵件上與朋友分享您對於喜愛書籍的看法。

2012年1月19日 星期四

Apple 推出 iBooks 2 電子教科書平台

這次的蘋果教育發表會辦在紐約的古根漢美術館,Phil Schiller 在發表會前半場,宣佈他們將推出 iBooks 2 的全新電子書平台,準備藉其「重新發明(改造)教科書」的發展。蘋果初期將先與幾間教科書的出版社如:Pearson, McGraw Hill 與 Houghton Mifflin Harcourt 合作,其內容將佔銷售的教科書籍約 90% 左右。現在,iBooks 2 也已經正式在 App Store 開放免費下載了,一般而言,平台上的教科書售價大約在 $15 美元(450 台幣/115 港幣)一本或更少 -- 這比起美國大學教科書平均 US$80 的價位要便宜的多呢!

參考新聞