iOS開發中iOS小結

一.內存管理情況
1- autorelease,當用戶的代碼在持續運行時,自動釋放池是不會被銷燬的,這段時間內用戶可以安全地使用自動釋放的對象。當用戶的代碼運行告一段 落,開始等待用戶的操作,自動釋放池就會被釋放掉(調用dealloc),池中的對象都會收到一個release,有可能會因此被銷燬。
2-成員屬性:
readonly:不指定readonly,默認合成getter和setter方法。外界毫不關心的成員,則不要設置任何屬性,這樣封裝能增加代碼的獨立性和安全性。相當於私有成員?
assign:表示只進行簡單的賦值,不會發送retain消息。
retain:會向舊值發送release消息,向新值發送retain消息。
copy:向舊值發release消息,向新值發送copy消息。
3-引用計數特殊情況:
NSArray:當把一個對象添加到NSArray時,對象的引用計數會加1,移除時會減1。
UIView:addGestureRecognizer會對手勢識別器的引用計數加1,removeGestureRecognizer會減1。

二 .圖形API
這個講的好,清晰明確:http://www.cocoachina.com/bbs/read.php?tid=77731&page=1
1-Quartz2D,的繪圖總是發生在圖形環境(Graphics Context)中。視圖會在調用drawRect:方法進行繪圖之前,創建好圖形環境,
通過UIGraphicsGetCurrentContext函數來獲得這個圖形環境。
如果直接在圖像或者PDF上繪圖,需要調用CGBitmapContextCreate或者CGPDFContextCreate函數來創建圖形環境。
Quartz2D繪圖的基礎元素是路徑。路徑可以是一些基礎幾何形狀,也可以是這些幾何形狀的組合。
當需要創建一條路徑時,應當調用CGContextBeginPath函數;
當需要將路徑繪製的起點移動到一個位置時,應當調用CGContextMoveToPoint函數;
當想繪製一條線段時,應當調用CGContextAddLineToPoint。 CTM(當前變換矩陣)將繪圖從用戶空間映射到設備控件。
當圖形環境剛剛創建時,CTM初始化爲一個單位矩陣。
對CTM進行平移變換應當調用CGContextTranslateCTM函數,進行旋轉變換應當調用CGContextRotateCTM函數,進行縮放變換應當調用CGContextScaleCTM函數。

2-UIBezierPath
使用UIBezierPath繪圖的好處:
-採用系統座標系
-在Core Graphics的基礎上封裝,具有Core Graphics的主要功能,無需考慮圖形環境。

    UIBezierPath* pathLines = [UIBezierPath bezierPath];
    [pathLines moveToPoint:point1]; // 移動到point1位置
    [pathLines addLineToPoint:point2]; // 畫一條從point1到point2的線
    pathLines.lineWidth = 5.0; // 線寬
    [UIColor redColor] set]; // 顏色設置
    [pathLines stroke]; // 開始描繪
在同一UIBazierPath中,只能採用相同的顏色和線寬。
可以調用closePath,從當前點畫一條直線到當前子路徑的初始點。如果要填充路徑,應當使用fill方法,此方法會填充路徑中得所有封閉子路徑。

三.容器
-NSArray和NSMutableArray
+array:創建一個空數組
+arrayWithArray:從另一個數組創建新的數組
+arrayWithContentsOfFile:讀文件創建數組
+arrayWithObject:創建一個數組,其中包含一個給定對象
+arrayWithObjects
+arrayWithObjects:count: 從C數組創建
-containsObject:是否包含一個元素
-count:數量
-lastObject:返回最後一個
-objectAtIndex:返回某一個
-objectsAtIndexes:返回一組,類型爲NSArray
-indexOfObject:返回對象索引
-arrayByAddingObject:原數組最後加一個對象,產生一個新的數組
-arrayByAddingObjectsFromArray:在原數組的最後添加另一個數組中的所有對象,產生一個新數組
-subarrayWithRange:抽取原數組中得一部分,產生一個新的數組
-isEqualToArray:比較兩個數組是否相同
-writeToFile:atomically:保存數組至一個文件
-writeToURL:atomically:保存數組至一個URL
-addObject:在數組最後添加一個對象
-addObjectsFromArray:在原數組最後添加另一個數組的全部對象
-insertObject:atIndex:向原數組制定位置添加一個對象
-insertObjects:atIndexes:向原數組中一系列位置添加一系列對象
-removeAllObjects:移除數組中的全部對象
-removeLastObject:移除數組中最後一個對象
-removeObject:移除一個對象
-removeObjectAtIndex:移除位於指定位置的對象
-removeObjectsAtIndexes:移除位於一系列位置的對象
-replaceObjectAtIndex:withObject用給定對象替換位於指定位置的對象
-replaceObjectsAtIndexes:withObjects:多對象,多位置版本
-setArray:用另一個數組中的所有對象來替換當前數組中的所有對象
-NSDictionary與NSMutableDictionary
+dictionary
+dictionaryWithContentsOfFile
+dictionaryWithContentsOfURL
+dictionaryWithDictionary
+dictionaryWithObject:forKey
+dictionaryWithObjects:forKeys
+dictionaryWithObjectsAndKeys
-count:數量
-allKeys:返回一個數組,包含字典中的所有關鍵字。
-allKeysForObject:返回一個數組,包含所有對應到給定對象的關鍵字。
-valueForKey:通過字符串查找數值。
-writeToFile:atomically
-writeToURL:atomically
-setValue:forKey: 加鍵-值對
-addEntriesFromDictionary: 添加另一個字典中得所有條目
-setDictionary:將原字典中條目設置爲另一個字典中得所有條目
-removeObjectForKey:移除一個關鍵字的對應條目
-removeAllObjects:移除所有條目
-removeObjectsForKeys:移除一系列關鍵字的對應條目

四.文件系統
1- 概述
bundle(沙盒):一個應用只能在自己的沙盒中讀取或存儲文件,而不能操作其他沙盒中的文件。好處:保護應用的隱私不受侵犯,保護系統文件的安排,應用刪除後相關文件也能被全部清除。
每個應用都有自己的沙盒,沙盒的根目錄的獲取方法是NSHomeDirectory()。
根目錄下的內容:
-.app文件,實際上是一個文件夾,包含了可執行文件、Nib文件、圖片資源、plist等。XCode中能看到的資源,及編譯後的可執行文件,都封裝在app中。
-Documents文件夾,用於存放你的應用所產生的數據,該文件夾可通過iTunes備份,可以存儲遊戲進度等。
-Library文件夾,用於存放用戶偏好和臨時文件。
-tmp文件夾是系統的中轉站。
2-文件管理器
NSFileManager,defaultManager()返回一個文件管理器的單例(多線程下不安全)。init(),在多線程編程中應儘量使用init()。
代理方法:-fileManager:shouldRemoveItemAtPath和-fileManager:shouldRemoveItemAtURL在移除操作之前被調用。
-removeItemAtPath:error:刪除位於指定路徑的文件、連接、目錄(及其所有子目錄、文件)。
-removeItemAtURL:error:同上。
-contentOfDirectoryAtPath:查找所有位於給定路徑的子路徑和文件。返回值爲一個數組,其中包含了NSString對象。查找只在當前目錄進行,不會進入下一層目錄。
-subpathsAtPath:查找給定路徑下的所有子路徑。深度查找,不限於當前層,也會查找package的內容。
-fileExistsAtPath:判斷文件是否位於一個路徑下面。
-isReadableFileAtPath:查詢文件的可讀性
-isWritableFileAtPath:可寫性
-isExecutableFileAtPath:查詢文件的可執行性
-isDeletableFileAtPath:可刪除性
3-NSString的路徑功能
-pathWithComponent:參數是一堆components構成的數組,返回的路徑是由這些components連接而成的路徑字符串,相鄰components之間用/隔開。
-pathComponents:返回一個數組,包含路徑中的components。
-fileSystemRepresentation:返回C字符串
-isAbsolutePath:判斷是否爲絕對路徑
-pathExtension:返回文件的擴展名,沒有的就返回空字符串
-stringByAppendingPathComponents :向現有路徑添加一個component。斜槓/會被自動加上
-stringByAppendingPathExtension:向現有路徑加上文件的擴展名
-stringByDeletingLastPathComponent:移除最後一個路徑component
-stringByDeletingPathExtension:刪除路徑擴展名
-stringByAppendingPaths:參數爲一個數組,此方法將數組中的字符串對象作爲路徑一次添加到源字符串後面。
例子:
NSString homePath = NSHomeDirectory();
NSString docPath = [homePath stringByAppendingFormat:@"/Documents"];

五.UIAlertController
    UIAlertController * alterVC = [UIAlertController alertControllerWithTitle:@"標題" message:alter preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * veryfiAction  = [UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {      
        NSLog(@"確認");
    }];
    [alterVC addAction:veryfiAction];
    [self.window.rootViewController presentViewController:alterVC animated:YES completion:nil];
六.旋轉
1- interfaceOrientation屬性查詢當前的界面方向。
2- rotatingHeaderView方法來查詢當前導航視圖。
3- rotatingFooterView來查詢當前的標籤條。
七.快速撥打電話接口
openURL能幫助你運行Maps,SMS,Browser,Phone甚至其他的應用程 序。這是Iphone開發中我經常需要用到的一段代碼,它僅僅只有一行而已。

[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://8004664411"];
這個程序通過基礎的協議支持撥打電話的功能。
八.區分設備類型的方法
打電話功能只有iPhone支持,對於其他設備對應按鈕應該禁用。

用[UIDevice currentDevice].model,這個返回的是一個NSString,你可以做如下判斷就能知道設備是iPad還是iPhone.
     if ([UIDevice currentDevice].model            
      rangeOfString:@"iPad"].location != NSNotFound) {
       NSLog(@"This is an iPad!");
}
用UI_USER_INTERFACE_IDIOM()方法,這是系統定義的一條宏。使用方法也很簡單。
 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)      
{
 NSLog(@"This is an iPad!");
 }
九.併發編程
1-GCD-Grand Central Dispatch,GCD使用隊列來管理多個任務,而每個任務是以塊(其定義類似於函數)來描述的。GCD從隊列中讀取這些要完成的任務,然後其多核執行 引擎負責將這些任務分配給它所管理的線程。和手動線程管理相比,GCD能極大地優化線程管理,並極大地減少創建和銷燬線程所帶來的額外開銷。除了在多核系 統上得性能改進之外,GCD還能幫助提高應用的響應速度,並讓代碼更爲乾淨,易於維護。
2-NSOperationQueue-操作隊列,可以極大地減少開發者在併發編程中的負擔,並且操作隊列有一套Objective-C的API,使用起來方便。
基本操作單位-NSOperation,操作。
操作是封裝了一個與任務有關的代碼與數據的抽象類,需要繼承NSOperation,並且描述相關的任務。操作對象是一次性的,它只能執行一次,下一次,需要創建一個新的實例。
可以通過addDependency:方法爲操作添加相互依賴性。假設操作A依賴於操作B,如果操作B沒有結束,操作A就不會開始執行。完成是指 執行完,或者取消了操作。有時需要對操作是否成功作出判斷。通過removeDependency:方法來移除操作的相互依賴性。
操作的一個屬性是isConcurrent。當使用操作隊列來管理這些操作時,isConcurrent應當設置爲NO,這時應當重載 NSOperation的main函數(在類中保存controller對象-weak,並在main中調用controller的方法)。 isReady屬性用於描述操作是否已經可以開始執行,isExecuting屬性表示操作是否正在執行當中,isFinished屬性表示操作是否順利 完成,isCancelled屬性則表示操作已經取消。
可以在操作運行中取消它的運行,只需要給它發送cancel消息即可。在繼承NSOperation類時,也需要支持cancel方法。
如果只需要簡單的操作,不想繼承NSOperation類,可以使用NSInvocationOperation類,這個類中的-initWithTarget:selector:object:方法能幫助你方便地選擇人物的對象和相應的功能。
操作的執行順序取決於各自的優先級和相互之間的依賴性。
操作隊列有兩種方式來執行其中的操作。第一種是開闢新線程來運行這些操作,第二種則是通過GCD來運行這些操作。但是無論如何,都不需要手動管理 線程。儘量使用操作隊列,只有在操作隊列的效率明顯不足時才轉向GCD。因爲操作隊列是封裝在GCD的基礎之上的,雖然增加了一些額外開銷,但是也具有更 加完善的功能。例子是TestNSOperation。

十.忙碌指示器
    UIActivityIndicator。
UIActivityIndicatorView *activityIndicatior = [UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicator.center = CGPointMake(512, 384);
    [self.view addSubview: activityIndicator];
    [activityIndicator startAnimating];  
    [activityIndicator stopAnimating];
    [activityIndicator removeFromSuperView];
十一.媒體播放
1- 音頻
[1] 音樂往往是存儲在iPod曲庫(注意位置)中的,可以通過媒體選擇器(media picker)或者媒體查詢(media query)讀取,然後用音樂播放器MPMusicPlayerController播放。

MPMusicPlayerController *musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setShufleMode: MPMusicShuffleModeSongs];
[musicPlayer setRepeatMode: MPMusicRepeatModeAll];
[musicPlayer setQueueWithQuery: [MPMediaQuery songsQuery];
[musicPlayer play];
applicationMusicPlayer返回的播放器,在你的應用中播放音樂。它不會影響到iPod播放器,也不能從iPod播放器重獲取信息。
iPodMusicPlayer返回的是iPod播放器,在你推出應用後,所有的設置都會影響到之後設備上的iPod播放器。
獲得音樂播放器後,需要爲它設置一個播放隊列。可以用setQueueWithQuery:放方法,通過媒體查詢MPMediaQuery來設置 播放隊列,也可以用setQueueWithItemCollection:方法,通過MPMdiaItemCollection來設置播放隊列。
重複模式repeatMode可以設置爲不重複、重複當前曲目、或整個播放列表;亂序播放shuffleMode可以設置爲不亂序、亂序播放曲目或亂序播放專輯;音量volume的設置與音頻播放器一樣。
skipToNextItem跳到下一首,skipToPreviousItem跳到上一首,skipToBegin跳到第一首。
對應的宏都是以MPMusic開頭。

    [2] 利用系統聲音服務來播放短暫音效(時長30秒以內),並震動:   
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);  
    播放指定音效:
NSURL *fileURL = [NSURL fileURLWithPath: path isDirectory: NO];  
// 創建音效ID
SystemSoundID soundID;
AudioServiceCreateSystemSoundID((CFURLRef) fileURL, &soundID);
// 播放聲音
AudioServicesPlaySystemSound(soundID);
[3] 音頻播放器

   沒有時長限制
NSURL *fileURL = [NSURL fileURLWithPath: path isDirectory: NO];
// 用URL來初始化音頻播放器-播放的不是iPod曲庫中的音樂
AVAudioPlayer* player = [AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: NO];
// 準備播放
[player prepareToPlay];
// 設置代理
[player setDelegate: self];
    方法:play、pause、stop。可以通過playing屬性查詢播放器是否正在播放當中,可以通過volume屬性來修改和查詢播放器的播放增益(從0.0到1.0),可通過setting屬性查詢播放器其他設置。

    duration表示音頻的時間長度, currentTime表示當前播放到的時間。播放結束後可以通過代理方法audioPlayerDidFinishPlaying:來處理播放後設置。
2- 視頻
視頻播放可以採用網頁視圖(UIWebView)進行嵌入式播放(能播放YouTube視頻),或者採用電影播放器(MPMoviePlayerController)進行播放。
[1] 電影播放器

MPMoviePlayerController *player = [MPMoviePlayerController alloc]initWithContentURL: url];
    // 設置播放器的大小,並將其加入視圖中
    [player.view setFrame: rectFrame];
    [self.view addSubView: player.view];
    播放器的背景視圖backgroundView。
    全屏[player setFullscreen: YES animated: YES];
    播放另一個影片[player setContentURL: newURL];
    [player requestThumbnailImagesAtTimes:arrayTimes timeOption:MPMovieTimeOptionNearestKeyFrame]; // 表示播放器不會在你所指定的時間去截取預覽,而是在絕對時間的附近幾幀中尋找效果最好的幀做爲預覽。
scalingMode規定了影片的縮放模式。   
initialPlaybackTime用來控制視頻開始播放的時間,單位是秒。
如果視頻源在網絡上,那麼需要正確設置服務器端的mimeType。

十二.運行環-runloop
運行環作用於一個iOS應用的整個生命週期。它負責監視各種輸入事件,並且在合適的時候對這些輸入進行分配。應用的每一個線程都有且僅有一個運行環。你自己不需要創建也不需要銷燬運行環,但是可以通過currentRunLoop方法來獲取當前的運行環。

十三.定時器
由於運行環機制,定時器的精度不高,只能用於一般性延時。
例子:拼圖遊戲,DeskViewController.m。
NSObject類的定時方法。
performSelector: withObject: afterDelay: 運行方法,參數,時間(秒)。
performSelectorOnMainThread: withObject: waitUntilDone: 在主線程中,運行參數selector所指定的方法,如果waitUntilDone參數爲YES,那麼當前線程會被阻攔,直到selector運行完。
performSelector: onThread: withObject: waitUntilDone:同上,但不一定在主線程中運行。
performSelectorInBackground: withObject: 開啓一個新線程,用於運行selector方法,selector方法應負責線程的初始化。
cancelPreviousPerformRequestsWithTarget:取消與一個目標相關的所有計劃好的動作。
cancelPreviousPerformRequestsWithTraget: selector: object只取消特定的計劃動作。
十四.隨機數
0~1之間隨機數

CG_INLINE float genRandomNum()
{
    return (float)arc4random/ARCRANDOM_MAX;
}
十五.地圖與連接服務器
[1] 添加框架MapKit.framework。使用MKMapView來呈現地圖。注意應當直接使用此類,而不是繼承之。如果希望在MKMapView類之上添加功能,可以使用MKMapViewDelegate協議。

初始化:
MKMapView *mapView = [MKMapView alloc] initWithFrame: rect];
    初始化之後並不直接顯示,還需要指定顯示的地圖區域:
CLLocationCoordinate2D coordinate;
coordinate.latitude = latitudeValue; // 緯度
coordinate.longtitude = longtitudeValue; // 精度
// 指定顯示區域,width和height單位都是米
mapView.region = MKCoordinateRegionMakeWithDistance(coordinate, width, height);
    之後可以通過addSubview添加地圖。
 屬性:showsUserLocation-爲YES,系統會持續跟蹤用戶的位置
          userLocationVisible-爲YES,將顯示用戶所在位置
顯示地圖之後,常常希望在地圖上添加標註,這需要創建一個類,並實現MKAnnotation協議,這個類叫做標註對象。標註對象往往實現 setCoordinate:方法來設置其座標。在地圖視圖上,可以設置標註對象的座標,然後添加進去,這樣地圖上就會出現一個標註。代理方法title 和subtitle能夠在標註上顯示標題和副標題。

// 初始化
   mapView = [MKMapView alloc] initWithFrame: CGRectMake(100, 100, 550, 700)];
   mapView.showsUserLocation = TRUE;
   mapView.mapType = MKMapTypeStandard;
   mapView.delegate = self;
   // 設置座標
   CLLocationCoordinate2D coordinate;
   coordinate.latitude = 37.31;
   coordinate.longtitude = -122.03;
   mapView.region = MKCoordinateRegionMakeWithDistance(coordinate, 4000, 6000); // 4000米寬,6000米高的區域
   [self.view insertSubview: mapView atIndex: 0];
十六.通過storyboard來初始化一個controller
CBigDesignImageViewController *imageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"BigImageController"];  
   BigImageController是要在storyboard中設置的Identifier屬性。
十七.給UIView子類設置陰影,包括各種控件
1 導入QuartzCore framework
2 #import
3 編碼:

[imgView layer] setShadowOffset:CGSizeMake(5, 5)]; // 陰影的範圍  
[imgView layer] setShadowRadius:2]; // 陰影擴散的範圍控制  
[imgView layer] setShadowOpacity:1]; // 陰影透明度  
// 陰影的顏色
[imgView layer] setShadowColor:[UIColor brownColor].CGColor];
十八.設置UIScrollView滾動速度
// 自動滾動太快,效果不好,這裏把動畫設置慢點,注意下面要直接賦值contentOffset,不要用帶animated參數的函數,否則動畫會出問題,因爲兩處都是動畫效果。   
  [UIScrollView animateWithDuration:1.0f  
                               delay:0  
                               options:UIViewAnimationCurveLinear
                               animations:^{
                                   scrollView.contentOffset = CGPointMake(0, 0);  
                               }
                               completion:^(BOOL finished){}
                               ];  
        // 如果在減速滾動過程中,按了刷新按鈕,執行上面的動畫,會出現重置的位置,y不是0的情況,這裏再調用一次,滾動到0。
        [scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
十九.EXC_BAD_ACCESS
Here’s the advice I generally give to developers when you hit an EXC_BAD_ACCESS error:
-Set the NSZombieEnabled argument in your executable options, which sometimes helps narrow down the cause
-Run with Apple Instruments such as Leaks to look for memory issues
-Set a breakpoint in your code and step through until you narrow down where it’s crashing
Tried and true “comment out code till it works” then backtrack from there :]
設置 NSZombieEnabled 的方法:
你可以點擊 Xcode 菜單 Product -> Edit Scheme -> Arguments, 然後將點擊”加號”, 將 NSZombieEnabled 參數加到 Environment Variables 窗口中, 後面的數值寫上 ”YES”.
或者在 Xcode4 菜單 Product -> Edit Scheme -> Diagnostics 設置窗口中直接勾上 Enable Zombie Objects 即可,Xcode 可用 cmd+shift+< 進到這個窗口。

二十 iOS 8 及 iOS 9
定位
在IOS8中定位功能新增了兩個方法:
- (void)requestWhenInUseAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);

- (void)requestAlwaysAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);
這兩個新增的方法導致,之前寫的程序在iOS8運行會出現,定位功能無法正常使用
這樣讓iOS8正常使用定位功能呢?

<1>你需要在info.plist表裏面添加兩條變量
在Info.plist中加入兩個缺省沒有的字段
NSLocationAlwaysUsageDescription//一直允許
NSLocationWhenInUseUsageDescription//使用時允許



iOS 9 網絡請求
iOS9把所有的http請求都改爲https了:iOS9系統發送的網絡請求將統一使用TLS 1.2 SSL。採用TLS 1.2 協議,目的是 強制增強數據訪問安全,而且 系統 Foundation 框架下的相關網絡請求,將不再默認使用 Http 等不安全的網絡協議,而默認採用 TLS 1.2。服務器因此需要更新,以解析相關數據。如不更新,可通過在 Info.plist 中聲明,倒退回不安全的網絡請求。
1.在Info.plist中添加NSAppTransportSecurity類型Dictionary。
2.在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型Boolean,值設爲YES。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章