// ********************** 判斷數組元素是否為空 **********************
NSString *element = [array objectAtIndex:2];
if ((NSNull *)element == [NSNull null]) {
}
今天做項目的時候就遇到,要判斷數組元素是否為空,我的以下寫法,都無效
if(!element)
if([element length]>0)
if(element== NULL)
if(element == Nil)
// ********************** 委托的格式 **********************
1 定義協議
@protocol uploadUserInfoDelegate
@required
-(void)uploadCallBack:(NSInteger )code msg:(NSString *)msg;
@end
2 定義委托屬性
@property (nonatomic, weak) id
3 調用
if ([self.delegate respondsToSelector:@selector(uploadCallBack:msg:)]) {
[self.delegate uploadCallBack:111 msg:@"mmm"];
}
4 實現方遵循協議 傳遞委托對象實現協議方法
@interface ViewController ()
obj.delegate = self;
-(void)uploadCallBack:(NSInteger )code msg:(NSString *)msg;
// ********************** block格式 **********************
1. 直接定義成屬性
@property (copy, nonatomic) void (^submitUserInfoBlock)(NSString* gender, NSInteger age, NSString* hobbys);
2. typedef定義成類型方便傳參
typedef void (^Callback)(NSInteger code, NSString* msg);
- (void)uploadUserInfoWith:(NSString*)name callBack:(Callback) callback;
3. typedef 定義類型再合成屬性
typedef void(^headerInputBlock)(NSString *inputStr);
@property(nonatomic,copy)headerInputBlock inputBlock;
4. 直接定義Block形參
- (AFHTTPRequestOperation *)httpGetWithMethodName:(NSString *) methodName
param:(id)parameters
response:(void (^)(id dict,NSError *error))callback;
// ********************** 創建單例 **********************
+ (ViewController *)shared
{
static ViewController* instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[ViewController alloc] init];
});
return instance;
}
// ********************** block 中的weakself **********************
block對於其變量都會形成strong reference,對於self也會形成strong reference,而如果self本身對block也是 strong reference的話,就會形成 strong reference 循環,造成內存洩露,為了防止這種情況發生,在block外部應該創建一個week(__block) reference。
所以在block內如果有self的話,一般都會在block外面加一句_block typeof(self)weakself = self;
__block typeof(self) weakself = self;
[self methodThatTakesABlock:^ {
[weakself doSomething];
}
// ********************** 類別的使用category可以擴展系統類和自定義類**********************
1. 新建類別文件NSString+Util
2.添加方法
@interface NSString (Util)
- (void)hello;
+ (void) say;
@end
3.實現方法
#import "NSString+Util.h"
@implementation NSString (Util)
- (void)hello {
NSLog(@"hello");
}
+ (void)say {
NSLog(@"static say.");
}
@end
4.在其它類中導入並調用
#import "NSString+Util.h"
NSString* mm = @"aa";
[mm hello];
[NSString say];
// ***************************** 獲取系統時間的時分秒 *****************************
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//設定時間格式,這裡可以設置成自己需要的格式
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString* dateString = [dateFormatter stringFromDate:now];
// ***************************** 定義宏weakSelf *****************************
#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
// ***************************** ViewController的代碼分組 *****************************
#pragma mark - Getters and Setters
#pragma mark - Init and Dealloc
#pragma mark - ViewController Lifecycle
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - CustomDelegate
#pragma mark - Custom View
#pragma mark - View Event
#pragma mark - Event Response
#pragma mark - GestureRecognizer
#pragma mark - Private Methods
// ***************************** xcode 有用的 tips *****************************
// TODO: 判斷登陸狀態,如果沒有登錄,顯示登錄界面。
// FIXME: 判斷登陸狀態,如果沒有登錄,顯示登錄界面
// ???: How does this work?
// !!!: Verify that all objects are accounted for
#warning This selector will not fire unless…
// ***************************** xcode @synthesize什麼時候不自動合成 *****************************
同時重寫了setter和getter時
重寫了只讀屬性的getter時
使用了@dynamic時
在 @protocol 中定義的所有屬性
在 category 中定義的所有屬性
重載的屬性
除了後三條,對其他幾個我們可以總結出一個規律:當你想手動管理@property的所有內容時,你就會嘗試通過實現@property的所有“存取方法”(the accessor methods)或者使用@dynamic來達到這個目的,這時編譯器就會認為你打算手動管理@property,於是編譯器就禁用了autosynthesis(自動合成)
當你同時重寫了setter和getter時,系統就不會生成ivar(實例變量/成員變量)。這時候有兩種選擇:
1.手動創建ivar
2.使用@synthesize foo = _foo;,關聯@property與ivar。
// ***************************** UIToolBar *****************************
1.工具欄UIToolBar管理了一組UIBarButtonItem,
UIBarButtonItem不能隨意擺放在屏幕上,它不是繼承自UIView。它由導航欄,標簽欄或工具欄管理。
欄按鈕條目UIBarButtonItem存儲工具欄和導航欄的按鈕的屬性,它本身不是按鈕。
2. UIBarButtonItem有兩種類型:按鈕元素,空白元素。
UIBarButtonSystemItem枚舉表示著不同的系統預設UIBarButtonItem;
UIBarButtonSystemItemFixedSpace類型表示一段空白,需要設置它的寬度值;可以使用它替換需要隱藏的項,以保持位置不變;
在UIToolBar開頭和末尾添加UIBarButtonSystemItemFlexibleSpace會使其它項有不同有水平對齊方式;
3.
初始化一個用於控制間距的UIBarButtonItem實例negativeSpacer,並設置negativeSpacer的width屬性的值,設為-5的時候,正好可以使按鈕與屏幕邊界值為0
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
target:nil action:nil];
/**
* width為負數時,相當於btn向右移動width數值個像素,由於按鈕本身和邊界間距為5pix,所以width設為-5時,間距正好調整
* 為0;width為正數時,正好相反,相當於往左移動width數值個像素
*/
negativeSpacer.width = -5;
leftItemsSupplementBackButton 設置是否只顯示你自定義的Backbuttuon默認NO 顯示自定義的
// ***************************** Category *****************************
、實現類別
同實現類相似,實現方法即可
2、類別的局限性
1.類別不能添加新的實例變量
2.命名沖突,如果類別中方法和類中已有方法同名,則類別具有更高優先級
3 類別的作用
1.將類的實現分散到多個不同文件或多個不同框架中
2.創建私有方法的前向引用
3.向對象添加非正式協議
4 利用類別分散實現
利用類別可以將類的方法分散到多個源文件中
特別指出的是:類別可以訪問其繼承的類的實例變量
在使用一個方法時,對象的方法是在接口中聲明、父類中聲明、還是類別中聲明並不重要
類別不僅可以分散實現到不同源文件,也可跨框架
5、使用類別創建前向引用
雖然可以實現未聲明的方法,但是編譯器會提出警告
通過類別可以提供聲明,而且,聲明的方法不必要一定在類別的實現中實現,也可以在類的實現中實現
6、非正式協議和委托類別
委托(delegage)是一種對象,另一個類的對象會要求委托對象執行它的某些操作
委托對象接受其它對象對它的特定方法的調用
其實就是委托對象必須實現別的對象調用的方法,與接口類似
7、 ITunesFinder項目
8 、委托和類別
委托和類別有什麼關系?委托強調類別的另一種應用:被發送給委托對象的方法可以聲明為一個NSObject的類別
創建一個NSObject的類別稱為“創建一個非正式協議”
9、響應選擇器
選擇器只是一個方法名稱,可以使用@selector()預編譯指令指定選擇器,其中方法名位於圓括號中,但它以OC運行時使用的特殊方式編碼,以快速執行查詢
NSObject提供了一個respondsToSelector的方法,詢問對象以確定其是否實現某個特定消息
10、選擇器的其他應用
選擇器可以被傳遞,可以作為方法參數,甚至可以作為實例變量存儲
// ***************************** NSIndexPath *****************************
1. indexPath.row 適用TableView
2. indexPath.item 適用於CollectionView
3. 設置UITableViewStyleGrouped可以讓header和footer隨tableview一起滾動
// ***************************** navigationBar and navigationItem *****************************
self.navigationItem.leftBarButtonItem = nil; //隱藏導航欄回退item
self.navigationController.navigationBar.hidden = YES; //隱藏整個導航欄
// ***************************** Masonry *****************************
Masonry NSAutoLayout 說明
left NSLayoutAttributeLeft 左側
top NSLayoutAttributeTop 上側
right NSLayoutAttributeRight 右側
bottom NSLayoutAttributeBottom 下側
leading NSLayoutAttributeLeading 首部
trailing NSLayoutAttributeTrailing 尾部
width NSLayoutAttributeWidth 寬
height NSLayoutAttributeHeight 高
centerX NSLayoutAttributeCenterX 橫向中點
centerY NSLayoutAttributeCenterY 縱向中點
baseline NSLayoutAttributeBaseline 文本基線
// ***************************** instancetype - id *****************************
①instancetype可以返回和方法所在類相同類型的對象,id只能返回未知類型的對象;
②instancetype只能作為返回值,不能像id那樣作為參數
// ***************************** tableView 動態Cell *****************************
{
BOOL cellIsSelected;
NSIndexPath* _indexPath;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell isSelected] && cellIsSelected == NO) {
cellIsSelected = YES;
_indexPath = indexPath;
} else {
cellIsSelected = NO;
}
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(cellIsSelected && _indexPath.row == indexPath.row) {
return 50 * 2.0;
}
return 50;
}
// ***************************** ios 異常崩潰 處理 *****************************
使用第三方庫 UncaughtExceptionHandler
可以檢測出常見錯誤,並友好的提示用戶 例如
1.NSArray、NSDictionary、NSString、KVC等問題引起的閃退。
2.解決NSObject performSelector找不到selector引起的閃退。
使用方法:
1、首先需要在appDelegate中使用InstallUncaughtExceptionHandler()用於監聽
2、添加UncaughtExceptionHandler這個類
iOS SDK提供的函數是NSSetUncaughtExceptionHandler來進行異常處理。但是無法處理內存訪問錯誤、重復釋放等錯誤,因為這些錯誤發送的SIGNAL。所以需要處理這些SIGNAL
4. SignalHandler不要在debug環境下測試。因為系統的debug會優先去攔截。我們要運行一次後,關閉debug狀態。應該直接在模擬器上點擊我們build上去的app去運行。而UncaughtExceptionHandler可以在調試狀態下捕捉
// ***************************** 指針和引用的區別 *****************************
1. 引用在語言內部用指針實現(如何實現?)。
2. 對一般應用而言,把引用理解為指針,不會犯嚴重語義錯誤。
3. 引用是操作受限了的指針(僅容許取內容操作)
// ***************************** iOS 集合的深復制與淺復制 *****************************
1. 在非集合類對象中:對immutable對象進行copy操作,是指針復制,mutableCopy操作時內容復制;對mutable對象進行copy和mutableCopy都是內容復制。用代碼簡單表示如下:
[immutableObject copy] // 淺復制
[immutableObject mutableCopy] //深復制
[mutableObject copy] //深復制
[mutableObject mutableCopy] //深復制
2. 在集合類對象中,對immutable對象進行copy,是指針復制,mutableCopy是內容復制;對mutable對象進行copy和mutableCopy都是內容復制。但是:集合對象的內容復制僅限於對象本身,對象元素仍然是指針復制。用代碼簡單表示如下:
[immutableObject copy] // 淺復制
[immutableObject mutableCopy] //單層深復制
[mutableObject copy] //單層深復制
[mutableObject mutableCopy] //單層深復制
// ********** ios文件夾:Documents, Library和 tmp 。Library包含Caches、Preferences目錄 **************
Documents:蘋果建議將程序創建產生的文件以及應用浏覽產生的文件數據保存在該目錄下,iTunes備份和恢復的時候會包括此目錄
Library:存儲程序的默認設置或其它狀態信息;
Library/Caches:存放緩存文件,保存應用的持久化數據,用於應用升級或者應用關閉後的數據保存,不會被itunes同步,所以為了減少同步的時間,可以考慮將一些比較大的文件而又不需要備份的文件放到這個目錄下。
tmp:提供一個即時創建臨時文件的地方,但不需要持久化,在應用關閉後,該目錄下的數據將刪除,也可能系統在程序不運行的時候清除。
1、Documents目錄
您應該將所有的應用程序數據文件寫入到這個目錄下。
這個目錄用於存儲用戶數據或其它應該定期備份的信息。
保存由應用程序產生的文件或者數據,例如:塗鴉程序生成的圖片,游戲關卡記錄
iCloud會自動備份Document中的所有文件。
上架注意 如果保存了從網絡上下載的文件,在上架審批的時候會被拒!
2、AppName.app目錄:這是應用程序的程序包目錄,包含應用程序的本身。由於應用程序必須經過簽名,所以您在運行時不能對這個目錄中的內容進行修改,否則可能會使應用程序無法啟動。
3、Library目錄:這個目錄下有兩個子目錄:Caches 和 Preferences
Preferences 目錄:包含應用程序的偏好設置文件。您不應該直接創建偏好設置文件,而是應該使用NSUserDefaults類來取得和設置應用程序的偏好.
系統偏好,用戶偏好,通過[NSUserDefaults standarDefaults]來直接操作
Caches 目錄:用於存放應用程序專用的支持文件,保存應用程序再次啟動過程中需要的信息。
緩存,保存網絡下載的文件,後續仍然需要繼續使用。例如:網絡下載的離線數據
緩存目錄中的文件系統不會自動刪除,可做離線訪問
程序必需要提供一個完善的清除緩存目錄的“解決方案”!
4、tmp目錄:用於存放臨時文件(臨時數據),保存應用程序再次啟動過程中不需要的信息。
臨時文件,保存在tmp中的文件,系統會自動回收,譬如磁盤空間緊張、重新啟動手機、應用退出後刪除
程序員不需要管tmp文件夾的釋放
// ***************************** UIApplication openURL *****************************
1.設置icon上的數字圖標
//設置主界面icon上的數字圖標,在2.0中引進,缺省為0
[UIApplicationsharedApplication].applicationIconBadgeNumber = 4;
2.設置搖動手勢的時候,是否支持redo,undo操作
//搖動手勢,是否支持redo undo操作。
//3.0以後引進,缺省YES
[UIApplicationsharedApplication].applicationSupportsShakeToEdit =YES;
3.判斷程序運行狀態
//判斷程序運行狀態,在2.0以後引入
/*
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
*/
if([UIApplicationsharedApplication].applicationState ==UIApplicationStateInactive){
NSLog(@"程序在運行狀態");
}
4.阻止屏幕變暗進入休眠狀態
//阻止屏幕變暗,慎重使用,缺省為no 2.0
[UIApplicationsharedApplication].idleTimerDisabled =YES;
慎重使用本功能,因為非常耗電。
5.顯示聯網狀態
//顯示聯網標記 2.0
[UIApplicationsharedApplication].networkActivityIndicatorVisible =YES;
6.在map上顯示一個地址
NSString* addressText =@"1 Infinite Loop, Cupertino, CA 95014";
// URL encode the spaces
addressText = [addressTextstringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString* urlText = [NSStringstringWithFormat:@"http://maps.google.com/maps?q=%@", addressText];
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:urlText]];
7.發送電子郵件
NSString *recipients =@"mailto:[email protected][email protected],[email protected]&subject=Hello from California!";
NSString *body =@"&body=It is raining in sunny California!";
NSString *email = [NSStringstringWithFormat:@"%@%@", recipients, body];
email = [emailstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:email]];
8.打電話到一個號碼
// Call Google 411
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"tel://8004664411"]];
9.發送短信
// Text to Google SMS
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"sms://466453"]];
10.打開一個網址
// Lanuch any iPhone developers fav site
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"http://itunesconnect.apple.com"]];
// ***************************** AFNetWorking https SSL認證 *****************************
// ***************************** ios File IO *******************************
數組、字典只能將BOOL、NSNumber、NSString、NSData、NSDate、NSArray、NSDictionary寫入屬性列表plist文件
NSFileHandle類主要對文件內容進行讀取和寫入操作
NSFileManager類主要對文件的操作(刪除、修改、移動、復制等等)
// ***************************** 加載本地html *******************************
- (void)loadExamplePage:(UIWebView*)webView {
NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];
[webView loadHTMLString:appHtml baseURL:baseURL];
}
- (void)loadDocument:(NSString*)docName {
NSString* path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
self.webView.scalesPageToFit = YES;
[self.webView loadRequest:request];
}
// ***************************** UIScrollView裡面嵌套UITableView這種結構是否合理? *******************************
Q: 類似網易新聞和lofter這種多標簽滾動切換的效果,我以為是在scrollview上添加tableview來實現的,但這樣實現感覺會導致ViewController臃腫不堪,實現delegate和datasource也比較混亂;想聽聽大家對於架構這種界面有什麼樣的建議,能提高代碼的復用還有把代碼剝離放到合適的地方;真的好想寫出結構清晰美觀的代碼啊思密達!
A: 每個標簽對應的列表可以是一個viewController,它負責這個列表的內容和一切的交互。scrollView裡裝的是viewController.view。
scrollView所在的viewController可以稱之為containerViewController,實際上起到了NavigationController之類的容器作用。而具體的內容,可以稱之為contentViewController。
它的好處:
同一個contentVC可以在不同的容器中自由地拆下和裝上,降低耦合,或者如題主所說“能提高代碼的復用還有把代碼剝離放到合適的地方”
可以做到動態地調整contentVC的數量,樣式也可以各不相同,只要是vc即可,題主圖中的網易新聞無疑是這麼做的佼佼者
可以通過“兩塊木板過河”這樣的原理,使用三個view來作為contentVC和scrollView的中間層,做到不論有多少個contentVC(比如網易新聞中添加很多標簽),同時加載在scrollView上的都只有3個
肯定還有,我一時沒想到。。。
總的來說,這種結構可以稱得上“清晰美觀”,但也要看實現者的水准,做得不好反而會帶來很多問題,做得好的。。。你看網易新聞多好用:)
/*************************** 動態口令 ****************************/
每次認證時令牌與服務器分別根據同樣的密鑰,同樣的隨機數和同樣的算法計算出認證時的動態口令,
動態密碼的密碼其實不是隨機的,而是由規律的。當下動態密碼分為兩類,時間性和事件性。何為時間性動態密碼?該類令牌產出動態密碼是以時間為參數的,而事件性一般以使用次數為參數的。我們以時間性動態為主要說明對象。整個驗證的過程如下:
1.動態密碼令牌產生動態密碼以時間和種子為參數,進行迭代,得出動態密碼,這裡的時間一般是秒數。每個時間性動態密碼令牌中會內置一個時鐘芯片。
2.服務器校驗動態密碼。服務器讀取系統時間加上種子,以相同的迭代方法得出動態密碼,然後雙方進行比對。
講到這邊,可能有所懷疑難道令牌的時間和服務器的時間一定會一致嗎?我的答案肯定是不一致的。那怎麼能檢驗的過去呢?原來很簡單,服務器校驗是是在一個時間區間裡校驗的,比如現在是12:00,服務器會生成11:55-12:05中所有的動態密碼,然後和令牌產生的動態密碼比對,這樣不就解決了時間不一致的問題了。另外服務器會把令牌和服務器相差的時間記錄下來,下次檢驗的會先把這個偏移值記錄下來,以減少動態密碼迭代次數,這樣就完成了另外一個比較重要的功能,偏移值自動調整。
顯示Mac隱藏文件的命令:defaults write com.apple.finder AppleShowAllFiles YES
隱藏Mac隱藏文件的命令:defaults write com.apple.finder AppleShowAllFiles NO
輸完單擊Enter鍵,退出終端,重新啟動Finder就可以了
重啟Finder:鼠標單擊窗口左上角的蘋果標志-->強制退出-->Finder-->重新啟動
/*************************** title使用self.navigationItem.title ****************************/
Q:樓主有沒有試過,在ViewDidLoad方法中,對self.title和self.navigationItem.title分別進行設置,出現的效果是一樣的?
A: 設置self.title會設置導航title,但是如果下面有tabBar,也會設置tabBarItem的title,所以還是單獨設置好一些,導航title使用self.navigationItem.title
/*************************** iOS6以後在UILabel顯示不同的字體和顏色 ****************************/
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"Using NSAttributed String"];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0,5)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(6,12)];
[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(19,6)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30.0] range:NSMakeRange(0, 5)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:10.0] range:NSMakeRange(6, 12)];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Courier-BoldOblique" size:30.0] range:NSMakeRange(19, 6)];
self.attrLabel.attributedText = str;
/*************************** xcode中的project.pbxproj沖突怎麼解決 ****************************/
1 添加或改動文件布局時先更新,改完後要立即提交,團隊成員都遵照這個約定。
/*************************** translucent IOS7 導航欄是否是半透明設置,子視圖是否從屏幕 0, 0開始 ****************************/
self.navigationController.navigationBar.translucent = NO;
/*************************** 保持程序在後台長時間運行 ****************************/
iOS上的VOIP程序是肯定能後台監測到來電並提示用戶的
VOIP的SIP報文走的是TCP通道,而語音報文走的是UDP通道。
在iOS平台中,NSStream即為TCP,並且NSStream有一個VOIP屬性,如果設置了,那麼你的程序處於後台時候,系統會托管你這個NSStream通道,並保持和服務器連接的暢通,如果這個時候服務器通過這個NSSream(TCP socket)給客戶端發送了數據,系統會激活你處於後台的程序運行10秒鐘已處理這個報文,你可以在這個時候通過LocalNotification來提示用戶有來電。
/*************************** 動態計算文字的高度 ****************************/
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16.0]}
CGSize size = [content boundingRectWithSize:CGSizeMake(UI_SCREEN_WIDTH, CGFLOAT_MAX) o
ptions: NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;
/*************************** 打開其它app ****************************/
使用[[UIApplication sharedApplication] canOpenURL:instagramURL];來判斷是否已安裝該APP,
使用[[UIApplication sharedApplication] openURL:fansPageURL];來打開該APP,若未安裝, 則默認在safari中打開相應頁面.
1. source app
NSURL *sourcePageURL;
sourcePageURL = [NSURL URLWithString:[NSString stringWithFormat:@"joejoe://%@", @"aaa"]]; //不能有空格
[[UIApplication sharedApplication] openURL:sourcePageURL];
2.target app
2.1 在taget->info->URL Types->URL Schemes設置name為mbc2m
// 獲取發送過來的值
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSString* str = [[url host] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
/**************************** 模擬用戶觸發事件 **************************/
UIControl有一個sendActionsForControlEvents消息,可以使用它手動觸發控件事件:
[button sendActionsForControlEvents:UIControlEventTouchUpInside]
[button sendAction:<#(nonnull SEL)#> to:<#(nullable id)#> forEvent:<#(nullable UIEvent *)#>]
/********************* 編碼問題導致NSURL初始化一直為null的解決辦法設置utf8編碼 **********************/
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
/********************* NSDictionary轉json str **********************/
- (NSString *)toJSONorNSString:(id )o
{
NSData *data=[NSJSONSerialization dataWithJSONObject:o options:NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments error:nil];
if (data == nil) {
return nil;
}
NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return str;
}
/***************************** MVVM ******************************/
在MVC的基礎上,把C拆出一個ViewModel專門負責數據處理的事情,就是MVVM。然後,為了讓View和ViewModel之間能夠有比較松散的綁定關系,於是我們使用ReactiveCocoa,因為蘋果本身並沒有提供一個比較適合這種情況的綁定方法。iOS領域裡KVO,Notification,block,delegate和target-action都可以用來做數據通信,從而來實現綁定,但都不如ReactiveCocoa提供的RACSignal來的優雅,如果不用ReactiveCocoa,綁定關系可能就做不到那麼松散那麼好,但並不影響它還是MVVM。
/***************************** 數組不轉化成實體類的好處 ******************************/
數組內容的轉化成本較高:數組裡面每項都要轉化成Item對象,如果Item對象中還有類似數組,就很頭疼。
轉化之後的數據在大部分情況是不能直接被展示的,為了能夠被展示,還需要第二次轉化。
只有在API返回的數據高度標准化時,這些對象原型(Item)的可復用程度才高,否則容易出現類型爆炸,提高維護成本。
調試時通過對象原型查看數據內容不如直接通過NSDictionary/NSArray直觀。
同一API的數據被不同View展示時,難以控制數據轉化的代碼,它們有可能會散落在任何需要的地方。