標籤:
一:如何去學習?都去學習什嗎?
1:學習優秀項目的設計思想,多問幾個為什麼,為什麼要這麼設計,這麼設計的好處是什麼,還能不能在最佳化 ,如何應用到自己的項目中 2:學習優秀項目的代碼風格,代碼的封裝設計思想,為什麼要這麼設計,這麼設計的好處是什麼,還能不能在最佳化 ,如何應用到自己的項目中,每行代碼都要用心去寫,每一行代碼都要力求使最簡潔的
3:學習別人遇到問題是如何分析問題,解決問題的方法是什麼
4:遇到新東西應該如何去學習:1:先研究要學習的東西作用是什麼 ,有什麼好處 2:如何使用:具體的文法知識 ,參照蘋果的API 3:使用情境:一般在項目中有什麼應用。
5:最重要的就是花大量的時間研究優秀的代碼,比別人想的深比別人想的遠,注意每一個細節,把每一個細節都要搞懂,把每一個細節做到極致,花大量的時間去實踐練習,將學習到的知識應用於項目中。
二:nullable, nonnull,null_resettable,_Null_unspecified 的關鍵字的認識
/* 1:介紹 怎麼去研究新特性? 1.使用新的xcode建立項目,用舊的xcode去開啟 Xcode7 2015 iOS9 Xcode6 2014 iOS8 Xcode5 2013 iOS7 Xcode4 2012 iOS6 1.出了哪些新特性 iOS9:關鍵字:可以用於屬性,方法傳回值和參數中 關鍵字作用:提示作用,告訴開發人員屬性資訊 關鍵字目的:迎合swift,swift是個強語言,swift必須要指定一個對象是否為空白 關鍵字好處:提高代碼規劃,減少溝通成本 關鍵字僅僅是提供警告,並不會報編譯錯誤 *//* 2:nullable: nullable:1.怎麼使用(文法) 2.什麼時候使用(作用) nullable作用:可能為空白 nullable 文法1 @property (nonatomic, strong, nullable) NSString *name; nullable 文法2 * 關鍵字 變數名 @property (nonatomic, strong) NSString * _Nullable name; nullable 文法3 @property (nonatomic, strong) NSString * __nullable name; *//* 3:nonnull nonnull:1.怎麼使用(文法) 2.什麼時候使用(作用) nonnull作用:不可為空 nonnull 文法1 @property (nonatomic, strong, nullable) NSString *name; nonnull 文法2 * 關鍵字 變數名 @property (nonatomic, strong) NSString * _Nonnull name; nonnull 文法3 @property (nonatomic, strong) NSString * __nonnull name; *//* 4:null_resettable: null_resettable:1.怎麼使用(文法) 2.什麼時候使用(作用) null_resettable:必須要處理為nil情況,重寫get方法 null_resettable作用:get方法不能返回nil,set可以傳入為空白 null_resettable 文法1 @property (nonatomic, strong, null_resettable) NSString *name; - (NSString *)name { if (_name == nil) { _name = @""; } return _name; } *//* 5:_Null_unspecified:不確定是否為空白 *//* 6: 1:關鍵字注意點 在NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之間預設是nonnull,一般前者寫在標頭檔之下,後者寫在end之上 2:關鍵字不能用於基礎資料型別 (Elementary Data Type)(int,float),nil只用於對象 3: @property (nonatomic) NSString *name;如此寫法,預設為strong修飾的 */#import "ViewController.h"@interface ViewController ()// nonnull// 沒有處理為空白的情況@property (nonatomic, strong, nonnull)NSString *name;@end@implementation ViewController//- (UIView *)view//{// if (_view == nil) {// [self loadView];// [self viewDidLoad];// }// return _view//}- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. }@end
三:泛型
#import "ViewController.h"/* 1:泛型介紹 泛型:限制類型 為什麼要推出泛型?迎合swift 泛型作用:1.限制類型 2.提高代碼規劃,減少溝通成本,一看就知道集合中是什麼東西 泛型定義用法:類型<限制類型>:NSMutableArray<NSString *> *arr,數組裡存放的都是字串類型 2:類的泛型聲明: 泛型聲明:在聲明類的時候,在類的後面<泛型名稱>:@interface Person<ObjectType> : NSObject 泛型僅僅是警示告 泛型好處:1.從數組中取出來,可以使用點文法:數組中存放元素的類型為id類型, id是不能使用點文法,但是利用泛型,給其限制類型,則從數組中取出對象後,可以利用點文法 2.給數組添加元素,有提示 3: 泛型在開發中使用情境: 1.用於限制集合類型:(集合類包括NSArray和NSSet,兩者用法相同,前者是有序的,而後者卻是無序的) 為什麼集合可以使用泛型?使用泛型,必須要先聲明泛型? => 如何聲明泛型 自訂泛型? 什麼時候使用泛型? 2: 在聲明類的時候,不確定某些屬性或者方法類型,在使用這個類的時候才確定,就可以採用泛型 自訂Person,會一些程式設計語言(iOS,Java),在聲明Person,不確定這個人會什麼,在使用Person才知道這個Person會什麼語言 如果沒有定義泛型.預設就是id 例如: 1;聲明泛型 #import <Foundation/Foundation.h> @interface Person<ObjectType> : NSObject // 語言 @property (nonatomic, strong) ObjectType language; @end 2:使用: Java *java = [[Java alloc] init]; iOS *ios = [[iOS alloc] init]; // iOS Person<iOS *> *p = [[Person alloc] init]; p.language = ios; // Java Person<Java *> *p1 = [[Person alloc] init]; p1.language = java; */#import "Person.h"#import "Java.h"#import "iOS.h"@interface ViewController ()@property (nonatomic, strong) NSMutableArray<NSString *> *arr;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; Java *java = [[Java alloc] init]; iOS *ios = [[iOS alloc] init]; // iOS Person<iOS *> *p = [[Person alloc] init]; p.language = ios; // Java Person<Java *> *p1 = [[Person alloc] init]; p1.language = java;}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ }@end
四:泛型的協變和逆變
#import "ViewController.h"/* 1: 泛型:限制類型 為什麼要推出泛型?迎合swift 泛型作用:1.限制類型 2.提高代碼規劃,減少溝通成本,一看就知道集合中是什麼東西 泛型定義用法:類型<限制類型> 泛型聲明:在聲明類的時候,在類的後面<泛型名稱> 泛型僅僅是警示告 泛型好處:1.從數組中取出來,可以使用點文法 2.給數組添加元素,有提示 泛型在開發中使用情境:1.用於限制集合類型 id是不能使用點文法 為什麼集合可以使用泛型?使用泛型,必須要先聲明泛型? => 如何聲明泛型 自訂泛型? 什麼時候使用泛型?在聲明類的時候,不確定某些屬性或者方法類型,在使用這個類的時候才確定,就可以採用泛型 自訂Person,會一些程式設計語言(iOS,Java),在聲明Person,不確定這個人會什麼,在使用Person才知道這個Person會什麼語言 如果沒有定義泛型.預設就是id 用於父子類型轉換 泛型:__covariant:協變, 子類轉父類 :也就是將子類的指標賦值給子類 __contravariant:逆變 父類轉子類:也就是將父類的指標賦值給子類 泛型注意點:在數組中,一般用可變數組添加方法,泛型才會生效,如果使用不可變數組,添加元素,泛型沒有效果,只是提示的作用 2:繼承:子類繼承父類後,父類可在.h中暴露方法例如初始化方法供子類去繼承 1:父類只暴露了初始化方法沒有重寫,子類繼承後,子類可以重寫,(子類在重寫時,盡量用self,不要用類名,避免其他類在繼承該類的時候,初始化得到的都是該類的對象,而不是繼承的子類的對象。)那麼子類重寫後,在父類中的self就為子類的對象,其中多個子類繼承同一個父類的時候,父類可以提供一個get的標識方法供子類重寫返回標識,從而在父類中來區分不同的子類 2:父類提供方法,供子類繼承,父類在實現該方法,則子類在外部調用初始化方法的時候,就會調用父類中實現的初始化方法。(新浪參數模型抽父類繼承的例子),若是子類又重寫父類的初始化方法,調用super會執行父類的方法,否則就不會執行父類的方法,會覆蓋掉父類的方法,只保留子類的方法 */#import "Person.h"#import "Java.h"#import "iOS.h"@interface ViewController ()@property (nonatomic, strong) NSMutableArray<NSString *> *arr;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; [_arr addObject:@"123"];// _arr = @[@"213",@"213",@1]; // Do any additional setup after loading the view, typically from a nib. iOS *ios = [[iOS alloc] init]; Language *language = [[Language alloc] init]; // 父類轉子類 Person<Language *> *p = [[Person alloc] init]; p.language = language; // iOS Person<iOS *> *p1 = [[Person alloc] init]; p1 = p; }// 子類轉父類- (void)covariant{ iOS *ios = [[iOS alloc] init]; Language *language = [[Language alloc] init]; // iOS Person<iOS *> *p = [[Person alloc] init]; p.language = ios; // Language Person<Language *> *p1; p1 = p;}- (void)test{ Java *java = [[Java alloc] init]; iOS *ios = [[iOS alloc] init]; // iOS Person<iOS *> *p = [[Person alloc] init]; p.language = ios; // Java Person<Java *> *p1 = [[Person alloc] init]; p1.language = java;}@end
五:__kindof
#import "ViewController.h"#import "SubPerson.h"/* kindof:相當於 __kindof:表示當前類或者它的子類‘, 類設計曆史 id:可以調用任何對象方法,可以作為參數或是傳回值,不能進行編譯檢查 instancetype:自動識別當前類的對象,只能作為傳回值不能作為參數,自動返回與當前類類型相同的對象 */@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; /** * 當父類提供初始化的方法的時候,子類繼承了父類的方法,若是子類SubPerson調用父類的初始化方法:person,則返回的是父類對象的類型,會出現警告,這時,可以在父類中定義的初始化方法用__kindof來修飾,表示當前類或是其子類。+ (__kindof Person *)person; */ SubPerson *p = [SubPerson person]; }@end
ios開發ios9新特性關鍵字學習:泛型,逆變,協變,__kindof