Objective-C 学习笔记
超類
即父類,通過 [super setName: @"a"] 可以調用超類方法
復合
是指一個對象由其他多個對象組成
對象初始化
@interface Car : NSObject (Engine *engine; ) @end@implementation Car - (id) init {//因init方法可能返回不同的對象,所以需要更新self。如從很長的字符串生成新字符串,初始化函數可能創建屬于其他類的對象,類似NSCFArray問題。實例變量的內存位置到隱藏self參數之間的距離是固定的,所以得保證init返回的對象,在后面引用能夠正確映射內存位置。if(self = [super init]){ engine = [Engine new];}return (self); } //init @end
若要超類可以完成所需的一次性初始化,需要調用[super init]。將[super init]的結果賦給self是oc的標準慣例。防止超類在初始化過程中返回的對象不同于原先創建的對象。
?Car *car = [[Car alloc] init] ?alloc先分配內存空間,并且內存初始化為0,指針為nil;init初始化對象。
new 和 alloc init可以說等價,但一般不用
#import
1、導入系統頭文件用 <>,導入項目本地頭文件用 ""
2、a.m 的implementation 時需要 #import "a.h"?
3、@interface中, a.m 可以使用 @class Engine 來告訴編譯器以后會知道這是個什么,implementation中還是需要#import。#import會告訴編譯器類的詳細信息,而@class只會告知這是一個類。#import循環依賴引用會報錯,而@class不會, A引用B,B引用A。不可以在子類里使用@class引用超類,因為那時候編譯器還不知道超類的信息。
?
內存管理
alloc、new、copy都會使引用計數+1
Mango *mango = [Mango new]; //count1 [mango retain]; //count 2 [mango release]; //count 1 [mango release]; // dealloc count1 //dealloc 后引用計數不一定是0,因為雖然對象已經銷毀,但是實際內存里的數據并沒有刪除?
訪問器
@property @synthesize ?編譯器自動生成get、set方法,不用成對出現
@synthesize (readwrite/readonly copy/retain) NSString *name;
1、readwrite 可讀寫,默認
2、readonly 只讀,只可調用get方法
3、copy 復制對象
4、retain 保留和釋放操作
5、copy/retain不指定則?賦值操作
?
類別
類別類似C#的擴展方法,方法可以不實現,編譯器不會抱錯,所以調用之前最好先檢查是否已實現。
@interface NSString (NumberConvenience類別名)- (NSNumber *) lengthAsNumber類別方法;@end@implementation NSString (NumberConvenience)- (NSNumber *) lengthAsNumber{unsigned int length = [self length];return ([NSNumber numberWithUnsignedInt: length]);}@end調用 NSNumber *length = [@"abc" lengthAsNumber];
?
類擴展
?為一個類添加額外的原來沒有的變量、方法或者合成屬性。
@interface MyClass () { //類擴展 float value; } - (void)setValue:(float)newValue; @end?類別與類擴展的區別:
①類別中只能增加方法;
②是的,你沒看錯,類擴展不僅可以增加方法,還可以增加實例變量(或者合成屬性),只是該實例變量默認是@private類型的(作用范圍只能在自身類,而不是子類或其他地方);
③類擴展中聲明的方法沒被實現,編譯器會報警,但是類別中的方法沒被實現編譯器是不會有任何警告的。這是因為類擴展是在編譯階段被添加到類中,而類別是在運行時添加到類中。
④類擴展不能像類別那樣擁有獨立的實現部分(@implementation部分),也就是說,類擴展所聲明的方法必須依托對應類的實現部分來實現。
⑤定義在 .m 文件中的類擴展方法為私有的,定義在 .h 文件(頭文件)中的類擴展方法為公有的。類擴展是在 .m 文件中聲明私有方法的非常好的方式。
協議
1、非正式協議其實是NSObject(子類)的一個類別,可選實現
選擇器@selector(方法) 和 obj respondToSelector:@Selector(方法) 能檢測對象是否支持此方法
2、正式協議 @protocol?
協議要求采用者必須實現列出的方法,不引入實例變量。2.0之前必須全部實現,2.0加入了 @required ?@optional 可選和必選
@protocol NSCopying //由cocoa聲明-(id) copyWithZone: (NSZone *) zone;@end@interface Engine : NSObject<NSCopying>//instance variables@end@implementation Engine -(id) copyWithZone: (NSZone *)zone {//[self class] 保證調用對象不管是父類還是子類都可以被復制不出錯Engine *engineCopy = [[[self class] allocWithZone: zone] init];return engineCopy; } @end@interface Tire : NSObject<NSCopying> {float pressure;float treadDepth; } //...methods @end 實現 -(id) copyWithZone: (NSZone *) zone {Tire *tireCopy = [[[self class] allocWithZone:zone]initWithPressure: pressuretreadDepth: treadDepth];return tireCopy; } Tire的子類AllWeatherRadial不需要<NSCopying>,因為繼承了父類的NSCopying @interface AllWeatherRadial : Tire {float rainHandling;float snowHandling; } //... methods @end 實現 -(id) copyWithZone: (NSZone *) zone {//子類只需調用父類已實現的copy方法來復制自身,父類使用的self class保證復制的是自己AllWeatherRadial *tireCopy = [super copyWithZone: zone];[tireCopy setRainHandling: rainHandling];[tireCopy setSnowHandling: snowHandling];return tireCopy; }?-(void) setObjectValue: (id<NSCopying>) obj; ? id<協議> 表示可以使用任意數據類型賦值,只要它實現了NSCopying協議
?
KVC 鍵值編碼
-valueForKey: ? -setValue:forKey:
如:NSNumber *number = [tire valueForKey:@"pressure"];
? ? ?[tire setValue: [NSNumber numberWithFloat: 12.0] forKey:@"pressure"];
kvc還可以使用路徑調用
NSNumber *level = [member valueForKey:@"memberExten.level"];
kvc可以進行一些計算返回
? ? ? NSNumber *count = [member valueForKey:@"invests.@count"]; ? 計算invest數組的數量
NSNumber *count = [member valueForKey:@"invests.@sum.amount"]; 計算投資總金額
NSNumber *count = [member valueForKey:@"invests.@max.amount"]; 計算最大投資額
NSNumber *count = [member valueForKey:@"invests.@avg.amount"]; 計算平均投資額
NSArray *loans = [member valueForKey:"@invests.distinctUnionOfObjects.loanId"]; 去重取出所有投標Id
NSDictionary *memberValues = [member dictionaryWithValuesForKeys: [NSArray arrayWithObjects: @"RegName", @"RealName", @"MobilePhone", nil]]; ?取出三個字段的值
NSDictionary *values = [member dictionaryWithValuesForKeys: [NSArray arrayWithObjects:@"RegName", @"RealName", nil]];? ? 取出值
? ? ? NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
?? ? ? ? ? ? ? ? ? ? ? ? ? ? @"Mango", @"RegName", [NSNumber numberWithInt:22], @"Age", nil];
? ? ? [member setValuesForKeysWithDictionary: dic]; ? 設置值
如果對象沒有對應的key,會放棄操作,并引發-setValue:forUndefinedKey:方法,可以重寫此方法做一些相應處理,比如存儲一個NSMutableDictionary,獲取方法為-valueForUndefinedKey:
如果為NSDictionary/NSMutableDictionary?setObject:forKey: 設置nil,會警告
如果為NSMutableDictionary?setValue:forKey: 設置nil,會刪除這個key
?
轉載于:https://www.cnblogs.com/mango03/p/4336228.html
總結
以上是生活随笔為你收集整理的Objective-C 学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何现实CITRIX XenAPP内容重
- 下一篇: getshell工具下载批量ecshop