記錄一下iOS開發中瑣碎的點點_1

1. 左側邊緣右滑推出控制器

實際上iOS7以後都是支持這個功能的. 導航控制器默認是支持這個功能的, 可是這個功能有個侷限, 當導航控制器包含自定義 leftBarButtonItem 時候, 右滑pop的功能就會失效.html

有個代理方法:安全

self.navigationController.interactivePopGestureRecognizer.delegate = nil;

當設置這個代理爲nil時候就能夠實現右滑推出的功能了, 可是咱們在項目中通常用另外一種方法:數據結構

#pragma mark - 實如今navi的非根控制器中, 在左側邊緣右滑推出控制器
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    //    self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    __weak typeof(self) weakSelf = self;
    self.navigationController.interactivePopGestureRecognizer.delegate = weakSelf;
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer{
    //判斷是否爲rootViewController
    if (self.navigationController && self.navigationController.viewControllers.count == 1) {
        return NO;
    }
    return YES;
}

首先將代理設置爲本控制器, 而後本控制器遵循UIGestureRecognizerDelegate協議, 實現其中的gestureRecognizerShouldBegin:方法, 在方法裏面判斷是不是根控制器, 若是不是容許右滑pop. 在項目中咱們通常把這些代碼放在BaseViewController中便可.ide

2. 加載storyboard中的控制器

2.1

我仍是更習慣用純代碼實現界面的,此次本身作練習,搭個很簡單的界面因而想用一下storyboard,建立一個storyboard文件, 拖個控制器, 拖幾個控件, 而後建立控制器時候, 是須要經過如下的方式來建立的,以下所示:函數

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"RouteNavigationViewController" bundle:[NSBundle mainBundle]];

UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"DaoHang"];

2.2

在晚上找到了以下的代碼:佈局

1> 下面的方法表示經過storyboard的名字從某個包中獲取(通常設置爲nil表示從主包中獲取)storyboard
+ (UIStoryboard *)storyboardWithName:(NSString *)name bundle:(NSBundle *)storyboardBundleOrNil
2> 此方法獲取到storyboard中初始的控制器
- (id)instantiateInitialViewController 
3> 此方法表示經過控制器的identifier獲取到此控制器,新版本的Xcode用Storyboard ID來表示某個控制器的identifier
- (id)instantiateViewControllerWithIdentifier:(NSString *)identifier;

總結:storyboard體驗仍是不錯的,拖控件嘛, 很簡單,很方便, 可是我想若是是很是複雜的界面, 不知道storyboard用起來怎麼樣, 我國我仍是更喜歡用代碼, 由於本身封裝UI控件, 使用代碼作UI也是頗有意思的一件事.測試

3. Objective-C中枚舉的移位操做

typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
    UIUserNotificationTypeNone    = 0,      
    UIUserNotificationTypeBadge   = 1 << 0, 
    UIUserNotificationTypeSound   = 1 << 1, 
    UIUserNotificationTypeAlert   = 1 << 2, 
}

4. iOS中UI控件的weak和strong

4.1 xib或者storyboard拖出來的控件通常使用weak 由於將控件拖到storyboard上面, 就已經構成了了一個view的層級關係, 已經有一個引用關係,在代碼中使用weak引用便可, 只有將view從父視圖上面移除,weak引用纔會被制空,可是在一個controller的生命週期內, 其子視圖通常都不會被移除掉, 因此用weak是可行的. 一個xib或者storyboard拖出來的控件,無論被定義成weak類型仍是strong類型,在viewController的生命週期內都是能夠的, 都不會形成循環引用和內存泄露.動畫

4.2 使用代碼自定義控件 以下兩個圖所示,第一個圖是storyboard拖得控件,聲明爲weak類型, 第二個圖是使用代碼聲明一個控件,也聲明爲weak類型,並用以下的方法去賦值, 這樣的賦值方法和直接拖一個控件在storyboard上面並在控制器中若引用效果和原理是徹底同樣的. 使用代碼直接聲明控件, 可使用以下的方式, 標標準準的強引用. 試驗證實,若是把控件聲明成weak類型,定義控件時候直接去賦值,這樣也是能夠的,點擊按鈕把weak類型變量制空, UI上面的控件並不會消失,我的認爲形成這樣的緣由是- (void)addSubview:(UIView *)view;這個方法的實現進行了copy操做. .net

結論, 無論使用哪一種方式建立view,常規的操做並不會形成循環引用和內存泄露.線程

5. masonry使用注意事項

通常使用masonry時候加上這兩個宏定義, 能方便不少.

#define MAS_SHORTHAND_GLOBALS使用全局宏定義,可使equalTo等效於mas_equalTo
 #define MAS_SHORTHAND使用全局宏定義, 能夠在調用masonry方法的時候不使用mas_前綴

6. AutoLayout關於更新的幾個方法的區別

  • setNeedsLayout:告知頁面須要更新,可是不會馬上開始更新。執行後會馬上調用layoutSubviews。
  • layoutIfNeeded:告知頁面佈局馬上更新。因此通常都會和setNeedsLayout一塊兒使用。若是但願馬上生成新的frame須要調用此方法,利用這點通常佈局動畫能夠在更新佈局後直接使用這個方法讓動畫生效。
  • layoutSubviews:系統重寫佈局
  • setNeedsUpdateConstraints:告知須要更新約束,可是不會馬上開始
  • updateConstraintsIfNeeded:告知馬上更新約束
  • updateConstraints:系統更新約束

7. UIKIT_EXTERN的含義

轉載自: http://blog.csdn.net/mrguanlingyu/article/details/23337885

// If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no
// NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init.
UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
這個函數被main.m調用做爲入口點來建立應用程序對象和應用程序委託,併成立了事件循環。
我這裏首先關注UIKIT_EXTERN這個宏定義,點進去會發現跳到UIKitDefines.h裏面,宏定義代碼以下:
#ifdef __cplusplus
#define UIKIT_EXTERN  extern "C" __attribute__((visibility ("default")))
#else
#define UIKIT_EXTERN          extern __attribute__((visibility ("default")))
#endif
其中__cplusplus 是cpp中的自定義宏,那麼定義了這個宏的話表示這是一段cpp的代碼,也就是說,上面的代碼的含義是:若是這是一段cpp的代碼,那麼加入extern"C"和其中的代碼。
extern是C/C++語言中代表函數和全局變量做用範圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量能夠在本模塊或其它模塊中使用。
那extern "C"呢?C++之父在設計C++之時,kao慮到當時已經存在了大量的C代碼,爲了支持原來的C代碼和已經寫好C庫,須要在C++中儘量的支持C,而 extern "C"就是其中的一個策略。
__attribute__是GNU C的一種機制,用法爲_attribute__ ((attribute-list))。當項目須要做爲一個庫被外包引用的時候一般在編譯時能夠用參數-fvisibility指定全部符號的可見性。在編譯命令中加入 -fvisibility=hidden參數,會將全部默認的public的屬性變爲hidden。此時,若是對函數設置__attribute__((visibility ("default")))參數,使特定的函數仍然按默認的public屬性處理,則-fvisibility=hidden參數不會對該函數起做用。因此,設置了-fvisibility=hidden參數以後,只有設置了__attribute__((visibility ("default")))的函數纔是對外可見的。
總結:若是須要讓類或方法可讓庫外被引用,就須要使用以上代碼確保代碼的可見性。

8. NSObject的load和initialize方法

轉載自:http://www.molotang.com/articles/1929.html

在Objective-C中,NSObject是根類,而NSObject.h的頭文件中前兩個方法就是load和initialize兩個類方法,本篇文章就對這兩個方法作下說明和整理。

Objective-C做爲一門面向對象語言,有類和對象的概念。編譯後,類相關的數據結構會保留在目標文件中,在運行時獲得解析和使用。在應用程序運行起來的時候,類的信息會有加載和初始化過程。

就像Application有生命週期回調方法同樣,在Objective-C的類被加載和初始化的時候,也能夠收到方法回調,能夠在適當的狀況下作一些定製處理。而這正是load和initialize方法能夠幫咱們作到的。

+ (void)load;
+ (void)initialize;

能夠看到這兩個方法都是以「+」開頭的類方法,返回爲空。一般狀況下,咱們在開發過程當中可能沒必要關注這兩個方法。若是有須要定製,咱們能夠在自定義的NSObject子類中給出這兩個方法的實現,這樣在類的加載和初始化過程當中,自定義的方法能夠獲得調用。

從如上聲明上來看,也許這兩個方法和其它的類方法相比沒什麼特別。可是,這兩個方法具備必定的「特殊性」,這也是這兩個方法常常會被放在一塊兒特殊提到的緣由。詳細請看以下幾小節的整理。

load和initialize的共同特色

load和initialize有不少共同特色,下面簡單列一下:

  • 在不kao慮開發者主動使用的狀況下,系統最多會調用一次
  • 若是父類和子類都被調用,父類的調用必定在子類以前
  • 都是爲了應用運行提早建立合適的運行環境
  • 在使用時都不要太重地依賴於這兩個方法,除非真正必要

load方法相關要點

廢話很少說,直接上要點列表:

  • 調用時機比較早,運行環境有不肯定因素。具體說來,在iOS上一般就是App啓動時進行加載(已測試),但當load調用的時候,並不能保證全部類都加載完成且可用,必要時還要本身負責作auto release處理。
  • 補充上面一點,對於有依賴關係的兩個庫中,被依賴的類的load會優先調用。但在一個庫以內,調用順序是不肯定的。
  • 對於一個類而言,沒有load方法實現就不會調用,不會kao慮對NSObject的繼承。
  • 一個類的load方法不用寫明[super load],父類就會收到調用,而且在子類以前。
  • Category的load也會收到調用,但順序上在主類的load調用以後。
  • 不會直接觸發initialize的調用。

initialize方法相關要點

一樣,直接整理要點:

  • initialize的天然調用是在第一次主動使用當前類的時候(lazy,這一點和Java類的「clinit」的很像)。
  • 在initialize方法收到調用時,運行環境基本健全。
  • initialize的運行過程當中是能保證線程安全的。
  • 和load不一樣,即便子類不實現initialize方法,會把父類的實現繼承過來調用一遍。注意的是在此以前,父類的方法已經被執行過一次了,一樣不須要super調用。 因爲initialize的這些特色,使得其應用比load要略微普遍一些。可用來作一些初始化工做,或者單例模式的一種實現方案。

9. 中止tableView的滑動

代碼中止tableView的滾動.

//Stop UITableView : UIScrollView from scrolling
[self.tableView setContentOffset:self.tableView.contentOffset animated:NO];

10. 使用UITextField或者UITextView長按選中彈出select文字中文

效果以下圖所示: 須要作的:

  1. 在Info.plist中修改 Localization native development region 爲China.
  2. 修改 Application Language, Application Regin. 以下:
相關文章
相關標籤/搜索