前言:本篇作為自己對Objective-C的基礎(chǔ)加強(qiáng)篇總結(jié)鲫剿,
整理各種OC知識點,會持續(xù)更新涂佃。
復(fù)習(xí)一下励翼,也為以后做準(zhǔn)備。
第一次整理Objective-C的內(nèi)容辜荠,如有錯誤和欠缺汽抚,
希望大神們提出,我修改伯病。
一造烁、內(nèi)存管理:MRC
管理內(nèi)存的分配和釋放
分配:alloc、new、copy 分配內(nèi)存
釋放:release
什么時候下會釋放內(nèi)存惭蟋?
當(dāng)計數(shù)器值為0時會自動釋放
怎么證明對象即將被釋放苗桂?
重寫dealloc方法
要求:
必須要調(diào)用父類的dealloc方法
內(nèi)存管理的原則:
誰創(chuàng)建,誰釋放告组。
誰retain煤伟,誰release
set的方法的內(nèi)存管理
- (void)setCat:(Cat *)cat
{
if(_cat != cat)
{
[_cat release];
_cat = [cat retain];
}
}
@property的標(biāo)準(zhǔn)格式和參數(shù)
- 格式:
@property(參數(shù)1,參數(shù)2)成員變量類型 成員變量名稱(去_) ;
- 參數(shù):
- nonatomic:非原子性,線程不加鎖,性能高,安全性低
atomic:原子性,線程加鎖,性能低,安全性高.
- retain:用于對象類型,生成set方法的內(nèi)存管理代碼.
assign:用于基本數(shù)據(jù)類型,不生成內(nèi)存管理代碼,直接進(jìn)行賦值操作.- readwrite:可讀可寫.
readonly:只讀- setter:更改set方法的名字,注意:setter:
getter:更改get方法的名字.
@class
簡單申明一個類
跟#import的區(qū)別:
import 引入文件里面所有的內(nèi)容,包括成員變量和方法惹谐。
@class 僅告訴編譯器持偏,有這個類
建議:在.h文件里使用@class
循環(huán)retain:
A包含B,B包含A
對象都無法釋放氨肌。
解決方法:一邊用assign,一邊用retain
NSString類的內(nèi)存管理
NSString是系統(tǒng)單獨做處理的酌畜,不能對其進(jìn)行內(nèi)存管理操作
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSMutableArray *ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[ary addObject:str];
NSLog(@"%@ %d",str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@"%@ %d",str,[str retainCount]);
[ary removeAllObjects];
NSLog(@"%@ %d",str,[str retainCount]);
return 0;
}
//注:NSString 不能手動管理內(nèi)存 而是由系統(tǒng)分配內(nèi)存
//運(yùn)行結(jié)果:全為-1
//2017-06-13 09:35:18.183653+0800 OC[602:14290] test -1
//2017-06-13 09:35:18.183846+0800 OC[602:14290] test -1
//2017-06-13 09:35:18.183868+0800 OC[602:14290] test -1
//Program ended with exit code: 0
二怎囚、內(nèi)存管理:ARC
自動釋放池
以前在創(chuàng)建1個對象時,需要在合適的位置調(diào)用release.
自動釋放池的作用:
對池子里面的所有對象,在池子被釋放時,統(tǒng)一做一次release操作.前提:調(diào)用autorelease,當(dāng)池子釋放時,才會對對象做release操作.
ARC的工作原理:
ARC不是垃圾回收,而是在編譯階段桥胞,在代碼合適的地方插入retain恳守、release、autorelease方法
strong和weak指針
在ARC中引入strong和weak指針贩虾,
如果對象有強(qiáng)指針引用則保留對象的存在催烘,否則立即回收。
__strong Person *p = [[Person alloc] init];
__weak Person *p = [[Person alloc] init];
注意:
1)有強(qiáng)指針引用缎罢,則對象存在伊群。
2)無強(qiáng)指針,即無引用或者弱指針引用策精,都會立即回收對象舰始,指針賦值為nil.
ARC中循環(huán)引用問題:
解決方案:一邊用strong,一邊用weak
如果兩邊同時strong會發(fā)生內(nèi)存泄漏咽袜。
ARC下 @property參數(shù):
strong用于OC對象丸卷,相當(dāng)于MRC中的retain
weak用于OC對象,相當(dāng)于MRC中的assign
assign用于基本類型询刹,與MRC中assign一樣
copy一般用于NSString谜嫉,與MRC中copy一樣
ARC使用注意事項:
1.不允許用release,retain,retainCount
2.允許重寫dealloc方法,但是不允許調(diào)用[super dealloc]
3.ARC中只要弱指針指向的對象不存在了凹联,該指針會自動清空沐兰,賦值為nil
4.下面代碼不能寫,不合理匕垫。 一創(chuàng)建就回收僧鲁。
__weak Person *p =[[Person alloc] init];
三、Category 范疇/分類
范疇作用:
1.對類的結(jié)構(gòu)進(jìn)行分類管理,便于團(tuán)隊開發(fā)以及維護(hù)
2.對類的方法進(jìn)行擴(kuò)展寞秃,提供新增方法
3.模擬現(xiàn)私有方法
//NSString+numeric類.h
#import <Foundation/Foundation.h>
@interface NSString(numeric)
-(BOOL)isNum;
@end
//NSString+numeric類.m
#import "NSString+numeric.h"
@implementation NSString(numeric)
-(BOOL)isNum{
for (int i=0; i<self.length; i++) {
unsigned short ch = [self characterAtIndex:i];
if (ch<'0'||ch>'9') {
return false;
}
}
return true;
}
@end
//main函數(shù)
#import <Foundation/Foundation.h>
#import "NSString+numeric.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *str = @"123";
BOOL isTrue = [str isNum];
NSLog(@"%d",isTrue);
NSString *str2 = @"abc";
BOOL isTrue2 = [str2 isNum];
NSLog(@"%d",isTrue2);
}
return 0;
}
Category使用的注意事項:
1.分類中只能添加方法斟叼,不能添加成員變量
2.分類中不允許屬性語法
3.出現(xiàn)重名方法,由編譯順序決定方法內(nèi)容
四春寿、非正式協(xié)議:informal protocol 繼承
給父類創(chuàng)建的分類朗涩,由子類實現(xiàn)方法。
//Person.h
#import <Foundation/Foundation.h>
@class Car;
@interface Person : NSObject
@property(nonatomic,weak)Car *car;
-(void)sayHello;
@end
//Student.h
#import "Person.h"
@interface Student : Person
@end
@implementation Student
-(void)sayHello{
NSLog(@"Hello,大家好绑改!");
}
@end
很簡單不多說谢床。
五、類拓展 class extension
所謂類擴(kuò)展厘线,是一個特殊的分類识腿。只是普通分類圓括號中有分類的名字。但是類擴(kuò)展沒有造壮。一般在.m文件中也會有渡讼。
也很簡單,不多說耳璧。
@interface person()
.....
@end
六成箫、Block 代碼塊/閉包
block允許訪問外部變量,但是不能改變旨枯,而是拷貝一個同樣的變量蹬昌,調(diào)用完block會回收,而外部變量不會發(fā)生改變攀隔。
七皂贩、protocol 協(xié)議
@protocol 協(xié)議名稱<NSObject> //默認(rèn)遵守NSObject 協(xié)議
//方法申明
@end
@interface 類名:父類名 <協(xié)議1,協(xié)議2竞慢,...>
@required(默認(rèn)先紫,必須實現(xiàn))
//成員方法...
@optional(可以不實現(xiàn))
//成員方法...
@end
只要采納了協(xié)議,相當(dāng)于已經(jīng)聲明了協(xié)議中的方法筹煮,只需要在implementation中實現(xiàn)該方法遮精。
OC不支持多繼承,但支持多協(xié)議败潦。
protocol使用注意:
1.protocol不能聲明成員變量
2.某個類遵守了協(xié)議本冲,就擁有了協(xié)議中的所有方法申明
3.父類遵循某個協(xié)議,子類也遵守
4.OC不能多繼承劫扒,但能多協(xié)議
5.協(xié)議可以遵循協(xié)議
八檬洞、代理設(shè)計模式:
1.有一個協(xié)議,關(guān)聯(lián)屬性和代理對象
2.一個目標(biāo)對象沟饥,可以有多個代理對象
3.在目標(biāo)對象中添怔,有id<協(xié)議>類型的屬性湾戳,作為代理屬性,可以賦值代理對象
4.給目標(biāo)對象發(fā)送消息广料,執(zhí)行代理對象中的方法
5.代理對象也實現(xiàn)協(xié)議中方法砾脑,是真正執(zhí)行代碼的對象,目標(biāo)對象只是發(fā)出一個通知艾杏。
代理模式常見類型:
1.監(jiān)聽模型:利用代理對象監(jiān)聽目標(biāo)的行為韧衣,一代目標(biāo)對象某個特征改變,觸發(fā)代理對象的行為(UIScrollView模型)
2.通知模型:目標(biāo)對象在某個條件下购桑,通知代理對象做某些事情(開槍畅铭,聽音樂等)
3.附加行為模型:需要為對象附加一些方法,但是不希望利用繼承完成勃蜘,所以附加代理對象完成硕噩。
九、NSString
1.stringWithFormat將格式化的字符串返回
NSString *s1 = [NSString stringWithFormat:@"一個字符串"];
NSString *s2 = [NSString stringWithFormat:@"一個字符串|%@",s1];
NSLog(@"%@",s1);
NSLog(@"%@",s2);
2.stringWithUTF8String OC中沒有字符串輸入函數(shù)元旬,只有用C語言中的輸入函數(shù)榴徐,再將C字符串轉(zhuǎn)換成OC字符串。
char arr[256];
scanf("%s",arr);
NSString *s = [NSString stringWithUTF8String:arr];
3.從文件或URL獲得字符串
- initWithContentsOfURL
- intitWithContentsOfFile
+ stringWithContentsOfURL
+ stringWithContentsOfFile
4.比較大性裙椤:
- (NSComparisonResult)compare:(NSString *)string;
5.前后綴檢查:
- (BOOL)hasPrefix:(NSString *)aString;
- (BOOL)hasSuffix:(NSString *)aString;
6.查找字符串:返回首次出現(xiàn)位置
- (NSRange)rangeOfString:(NSString *)aString;
NSRange:Foundation中頻繁使用的結(jié)構(gòu)體
7.字符串的截取:
- (NSString *)substringFromIndex:(NSUInteger)from; //從開頭到結(jié)尾
- (NSString *)substringToIndex:(NSUInteger)to; //開頭到該位置
- (NSString *)substringWithRange:(NSRange)range; //截取NSRange
8.字符串的替換
- (NSString *)stringByReplacingOccurrenceOfString:(NSString *)target;
十耗帕、NSMutableString
1.追加:
- (void)appendString:(NSString *)aString;
- (void)appendFormat:(NSString *)format,...;
2.插入:
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
3.刪除:
- (void)deleteCharactersInRange:(NSRange)range;
4.替換
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString)...
十一穆端、NSArray
1.寫入文件:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile...
2.讀取數(shù)據(jù):
+ (NSArray *)arrayWithContentsOfFile:(NSString *)path;
- (NSArray *)initWithContentsOfFile:(NSString *)path;
3.數(shù)組連接成字符串
- (NSString *)componentsJoinedByString:(NSString *)separator;
4.字符串拆成數(shù)組
- (NSArray *)componentsSeparatedByString:(NSString *)separator;
十二、NSMutableArray
1.新增數(shù)據(jù):
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
2.刪除數(shù)據(jù):
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeObject:(id)anObject;
3.修改數(shù)據(jù):
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject...
4.交換元素:
- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:...
十三仿便、NSDictionary
1.字典的數(shù)據(jù)存儲体啰,鍵值必須一一對應(yīng),同時鍵不允許重復(fù)
2.鍵值對是散列數(shù)據(jù)嗽仪,是沒有順序的
3.鍵值對集合利用count返回長度荒勇,表示有幾組鍵值對
4.鍵值對集合使用下標(biāo)訪問對應(yīng)鍵的值,早期使用objectForKey方法
1.創(chuàng)建字典
+ dictionaryWithObject:(id)object forKey:(id <NSCopying>....)
- initWithObjects:(const id [])objects forKeys:(const id ....)
+ dictionaryWithObjectsAndKeys:(id)firstObject,....
- initWithObjectsAndKeys:(id)firstObject,...
2.遍歷字典
//for-in循環(huán)遍歷
for(NSString *key in dic){
NSLog(@"%@ = %@",key, dic[key]);
}
//使用block遍歷
- (void)enumerateKeysAndObjectsUsingBlock:(void(^)(id key, id obj,...));
3.文件操作:
+ (NSDictionary *)dictionaryWithContentsOfFile:(NSString *)path;
+ (NSDictionary *)dictionaryWithContentsOfURL:(NSURL *)url;
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile...
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)atomically;....
十四闻坚、NSMutableDictionary
常用方法:
- (void)removeObjectForKey:(id)aKey;
- (void)setObject:(id)anObject forKey:(id <NSCopying>)aKey;
- (void)removeAllObjects;
//插入可以使用
dic[key]= value;
十五沽翔、NSFileManager
NSFileManager對文件進(jìn)行管理,包括創(chuàng)建窿凤,復(fù)制仅偎,移動,刪除...
它是一個單例的存在雳殊,整個程序只允許有一個該對象橘沥。
使用defaultManager方法可以獲得該對象
1.常用方法:
- (BOOL)fileExistsAtPath:(NSString *)path;
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory...
- (BOOL)isReadableFileAtPath:(NSString *)path;
- (BOOL)isWriteableFileAtPath:(NSString *)path;
- (BOOL)isExecutableFileAtPath:(NSString *)path;
- (BOOL)isDeletableFileAtPath:(NSString *)path;
2.獲取文件:
- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError *)....
3.獲取目錄下內(nèi)容
- (NSArray *)subpathsAtPath:(NSString *)path;
- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:....
4.獲得當(dāng)前目錄下內(nèi)容
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError *)....
5.對文件進(jìn)行增刪改查
//創(chuàng)建文件
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data ....
//創(chuàng)建文件夾
- (BOOL)createDirectoryAtPath:(NSString *)path attributes:(NSDictionary *)....
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirection....
//復(fù)制文件
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath...
//剪切文件
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error....
十六、SandBox 沙盒
沙盒是文件系統(tǒng)目錄夯秃,蘋果沒有開放安全座咆、隱私等方面的內(nèi)容痢艺。
所有的app都是在自己的沙盒中運(yùn)行,不能實現(xiàn)跨沙盒運(yùn)行介陶。
這種架構(gòu)主要出于兩方面考慮:
1.完美的用戶體驗堤舒,需要對跨應(yīng)用程序進(jìn)行整合統(tǒng)一
2.封閉跨應(yīng)用可以保證系統(tǒng)的安全性
iOS8后開放訪問(extension): 一種對幾個固定系統(tǒng)區(qū)域的擴(kuò)展機(jī)制,在一定程度上彌補(bǔ)iOS的沙盒機(jī)制對應(yīng)用間通信的限制斤蔓。它為用戶提供了在其他應(yīng)用提供的服務(wù)的便捷方式植酥。
獲取沙盒路徑:
//Home目錄
NSString *homeDirectory = NSHomeDirectory();
獲取絕對路徑的方法:
NSSearchPathForDirectoriesInDomains;
第一個參數(shù):要獲取的沙盒文件夾名稱
第二個參數(shù):
NSUserDomainMask = 1, //用戶主目錄中
NSLocalDomainMask = 2, //當(dāng)前機(jī)器中
NSNetworkDomainMask = 4, //網(wǎng)絡(luò)中可見的主機(jī)
NSSystemDomainMask = 8, //系統(tǒng)目錄,不可修改(/System)
NSAllDomainsMask = 0x0fff, //全部
第三個參數(shù):YES/NO 是否獲取全路徑
十七弦牡、常見結(jié)構(gòu)體
頁面布局:
NSPoint 與 CGPoint
NSSize 與 CGSize
NSRect 與 CGRect
CoreGraphics
Make函數(shù)
官方建議使用CG友驮。
十八、NSNumber
在OC中驾锰,數(shù)組和字典不允許存儲基礎(chǔ)數(shù)據(jù)類型(int卸留,float等)
要想存儲基本數(shù)據(jù)類型,就包裝廠NSNumber對象類型椭豫,再存入字典數(shù)組
十九耻瑟、NSValue
存儲C或OC數(shù)據(jù),是一個數(shù)據(jù)的容器赏酥,相當(dāng)于對NSNumber的擴(kuò)展
+ (NSValue *)valueWithPoint:(NSPoint)point;
+ (NSValue *)valueWithSize:(NSSize)size;
+ (NSValue *)valueWithRect:(NSRect)rect;
二十喳整、NSDate
1.獲取當(dāng)前時間:
[NSDate date];
2.格式化日期:
使用NSDateFormatter的dateFormat屬性設(shè)置時間格式字符串
- (NSString *)stringFromDate:(NSDate *)date;
- (NSDate *)dateFromString:(NSString *)string;
3.計算:
OC中使用NSTimeInterval表示時間間隔
在當(dāng)前時間上添加秒數(shù):
- (id)addTimeInterval:(NSTimeInterval)seconds NS_DEPRECATED...
+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;
二十一、copy
copy就是創(chuàng)建一個副本與源沒有直接關(guān)系裸扶,修改其中一個框都,對另一個沒有影響
- OC中的copy就是對象的復(fù)制:
一個對象可以調(diào)用一個copy方法或mutableCopy方法進(jìn)行拷貝
copy創(chuàng)建的是不可變副本(NSString、NSArray呵晨、NSDictionary)
mutableCopy創(chuàng)建可變副本
- 使用copy與mutableCopy:
copy:遵守NSCopying協(xié)議魏保,實現(xiàn)copyWithZone方法
mutableCopy:遵守NSMutableCopying協(xié)議,實現(xiàn)mutableCopyWithZone方法
- 深拷貝與淺拷貝:
深拷貝:產(chǎn)生了新的對象摸屠,是兩個對象谓罗,創(chuàng)建了一塊新的內(nèi)存地址
淺拷貝:沒有產(chǎn)生了新的對象,是一個對象季二,使用源內(nèi)存地址
4.@property中的copy
MRC中:
1)copy:用于NSString/Block
2)retain:除NSString/Block外的OC對象
3)assign:基本數(shù)據(jù)類型檩咱、枚舉、結(jié)構(gòu)體(非OC對象)戒傻,當(dāng)兩個對象互相引用税手,一端用retain,一端用assign.
ARC中:
1)copy:用于NSString/Block
2)strong:除NSString/Block外的OC對象
3)weak:當(dāng)兩個對象互相引用時需纳,一端用strong芦倒,一端用weak
4)assign:基本數(shù)據(jù)類型、枚舉不翩、結(jié)構(gòu)體(非OC對象)
//本質(zhì):
- (void)setName:(NSString *)name{
if (_name == name) return;
[_name release];
_name = [name copy];
}
二十二兵扬、單例設(shè)計模式 Singleton
- 定義:類的對象成為系統(tǒng)中唯一的實例麻裳,提供 "唯一" 一個訪問點,供客戶類共享資源器钟。
- 什么時候使用津坑?
1)類只能有一個實例,并且必須從一個為人熟知的訪問點對其進(jìn)行訪問傲霸,比如工廠方法疆瑰。
2)這個唯一的實例只能通過子類化進(jìn)行擴(kuò)展,而且擴(kuò)展的對象不會破壞客戶端代碼昙啄。
- 設(shè)計要點:
1)某個類只能有一個實例
2)他必須自行創(chuàng)建這個對象
3)必須自行向整個系統(tǒng)提供這個實例
4)為了保證實例的唯一性穆役,需要注意用好:
-(id)copyWithZone:(NSZone *)zone
+(id)allocWithZone:(NSZone *)zone
//以下僅MRC中:
-(id)retain
-(NSUInteger)retainCount
-(oneway void)release
-(id)autorelease
- 實例代碼:
//SingleTools.h
@interface SingleTools : NSObject
@property(nonatomic,assign)int num;
@property(nonatomic,copy)NSString *test;
+(instancetype)shareInstances;
@end
//SingleTools.m
#import "SingleTools.h"
static SingleTools *instance = nil;
@implementation SingleTools
+(instancetype)shareInstances{
if (instance == nil) {
instance = [[self allocWithZone:NULL] init ];
}
return instance;
}
-(id)copyWithZone:(NSZone *)zone{
return self;
}
+(id)allocWithZone:(struct _NSZone *)zone{
@synchronized (self) {
if (instance == nil) {
instance = [super allocWithZone:zone];
return instance;
}
}
return instance;
}
/* MRC中:
-(id)retain{
return self;
}
-(NSUInteger)retainCount{
return NSUIntegerMax;
}
-(oneway void)release{
}
-(id)autorelease{
return self;
}
*/
@end