iOS 開発の結(jié)構(gòu)
畫面
UI
UIWebview
[[UIApplication sharedApplication] openURL:]
調(diào)用谷歌地圖(Google Maps)
NSString *searchQuery = @"1 Infinite Loop, Cupertino, CA 95014";
searchQuery = [addressText stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSString *urlString=[NSString stringWithFormat:@"http://maps.google.com/maps?q=%@", searchQuery];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlText]];
調(diào)用郵件客戶端(Apple Mail)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@eyecm.com"]];
撥號(hào)(Phone Number)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]];
調(diào)用短信(SMS)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:10086"]];
調(diào)用瀏覽器(Safari Browser)
NSURL *url= [NSURL URLWithString:@"http://eyecm.com"];
[[UIApplication sharedApplication] openURL:url];
調(diào)用應(yīng)用商店(AppStore)
NSURL *appStoreUrl= [NSURL URLWithString:@"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=291586600&mt=8"];
[[UIApplication sharedApplication] openURL:appStoreUrl];
調(diào)用appstore中程序的評(píng)論
NSString *str = [NSString stringWithFormat:
@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%d",
m_appleID ];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
// 啟動(dòng)系統(tǒng)風(fēng)火輪
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// 隱藏系統(tǒng)風(fēng)火輪
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
畫面の切り替え
UINavgationController
UIBarButtonItem* next =?[[[UIBarButtonItem alloc] initWithTitle:@"閉じる"
style:UIBarButtonItemStyleBordered
target:modalViewController
action:@selector(touchedCloseModalViewControler)] autorelease];
modalViewController.navigationItem.leftBarButtonItem = next;
UINavigationController *navigationController =?[[[UINavigationController alloc] initWithRootViewController:modalViewController] autorelease];
[self presentViewController:navigationController animated:YES completion:nil];
[self.navigationController pushViewController:detail animated:YES];
[self.navigationController popViewControllerAnimated:YES];
[self presentViewController:navigationController animated:YES completion:nil];
Network
NSURLSession
配置
image.xcassets
Prefix.pch
#ifdef __OBJC__
#endif
Info.plist
//獲取當(dāng)前版本號(hào)
NSDictionary*infoDic = [[NSBundlemainBundle]infoDictionary];
NSLog(@"%@",infoDic);
NSString?*currentAppVersion = infoDic[@"CFBundleShortVersionString"];
// contentView.plist読み込み準(zhǔn)備
NSString *path = [[NSBundle mainBundle] pathForResource:@"contentView" ofType:@"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSString?*executableFile?=?[[[NSBundle?mainBundle]?infoDictionary]?objectForKey:(NSString?*)kCFBundleExecutableKey];
//獲取項(xiàng)目名稱
NSString?*version?=?[[[NSBundle?mainBundle]?infoDictionary]?objectForKey:(NSString?*)kCFBundleVersionKey];
//獲取項(xiàng)目版本號(hào) NSDictionary?*infoDictionary?=?[[NSBundle?mainBundle]?infoDictionary]; ?CFShow(infoDictionary); //?app名稱
NSString?*app_Name?=?[infoDictionary?objectForKey:@"CFBundleDisplayName"];
//?app版本
NSString?*app_Version?=?[infoDictionary?objectForKey:@"CFBundleShortVersionString"];
//?app?build版本
NSString?*app_build?=?[infoDictionary?objectForKey:@"CFBundleVersion"];
performSelectorOnMainThread的一些細(xì)節(jié)
#pragma mark 加載圖片
-(void)loadImage{
//請(qǐng)求數(shù)據(jù)
NSData *data= [self requestData];
/*將數(shù)據(jù)顯示到UI控件,注意只能在主線程中更新UI,
另外performSelectorOnMainThread方法是NSObject的分類方法韧献,每個(gè)NSObject對(duì)象都有此方法,
它調(diào)用的selector方法是當(dāng)前調(diào)用控件的方法,例如使用UIImageView調(diào)用的時(shí)候selector就是UIImageView的方法
Object:代表調(diào)用方法的參數(shù),不過只能傳遞一個(gè)參數(shù)(如果有多個(gè)參數(shù)請(qǐng)使用對(duì)象進(jìn)行封裝)
waitUntilDone:是否線程任務(wù)完成執(zhí)行
*/
[self performSelectorOnMainThread:@selector(updateImage:) withObject:data waitUntilDone:YES];
}
NSThread->1.0創(chuàng)建線程
第一種:通過NSThread的對(duì)象方法(alloc / init - start)
//線程一啟動(dòng)座泳,就會(huì)在線程thread中執(zhí)行self的run方法
NSThread*thread = [[NSThreadalloc]initWithTarget:<#(nonnull id)#>
selector:<#(nonnull SEL)#>
object:<#(nullable id)#> ];
//開啟線程,通過start方法,就會(huì)將我們創(chuàng)建出來的當(dāng)前線程加入到`可調(diào)度線程池`,供CPU調(diào)度
//[thread start];執(zhí)行后污茵,會(huì)在另外一個(gè)線程執(zhí)行l(wèi)ongOperation:方法
[thread start];
第二種:通過NSThread的類方法(detachNewThreadSelector)
// detachNewThreadSelector類方法不需要啟動(dòng),會(huì)自動(dòng)創(chuàng)建線程并執(zhí)行@selector方法
//它會(huì)自動(dòng)給我們做兩件事:? 1.創(chuàng)建線程對(duì)象2.添加到`可調(diào)度線程池`
//通過NSThread的類和NSObject的分類方法直接加入到可調(diào)度線程池里面去,等待CPU調(diào)度
[NSThreaddetachNewThreadSelector:<#(nonnullSEL)#>
toTarget:<#(nonnullid)#>
withObject:<#(nullableid)#> ];
第三種:通過NSObject的方法
//此方法在后臺(tái)線程中執(zhí)行(即是:在子線程中執(zhí)行)
// performSelectorInBackground是NSObject的分類方法,會(huì)自動(dòng)在后臺(tái)線程執(zhí)行@selector方法
//沒有thread字眼,隱式創(chuàng)建并啟動(dòng)線程
//所有NSObject都可以使用此方法温算,在其他線程執(zhí)行方法
//通過NSThread的類和NSObject的分類方法直接加入到可調(diào)度線程池里面去,等待CPU調(diào)度
// PerformSelectorInBackground可以讓方便地在后臺(tái)線程執(zhí)行任意NSObject對(duì)象的方法
[selfperformSelectorInBackground:<#(nonnull SEL) #>
withObject:<#(nullable id) #> per];
方式2和方式3的優(yōu)缺點(diǎn) :
優(yōu)點(diǎn):簡單快捷
缺點(diǎn):無法對(duì)線程進(jìn)行更詳細(xì)的設(shè)置
NSThread->2.0線程屬性
線程相關(guān)方法:
+ (NSThread*)mainThread;//獲得主線程
- (BOOL)isMainThread;//是否為主線程
+ (BOOL)isMainThread;//是否為主線程
NSThread*main = [NSThreadmainThread];// + (NSThread *)mainThread;獲得主線程
[NSThreadisMainThread];//? + (BOOL)isMainThread;類方法判斷她肯,該方法是否為主線程
[main isMainThread];//? - (BOOL)isMainThread;對(duì)象方法判斷佳头,該對(duì)象是否為主線程
NSThread*current = [NSThreadcurrentThread];//獲得當(dāng)前線程
//返回當(dāng)前方法所在線程的優(yōu)先級(jí)
+ (double)threadPriority;
舉例:[NSThreadthreadPriority];
//設(shè)置線程的優(yōu)先級(jí)
+ (BOOL)setThreadPriority:(double)p;
舉例:self.thread1.threadPriority=1.0;
- (double)threadPriority;//返回當(dāng)前方法所在線程的優(yōu)先級(jí)
- (BOOL)setThreadPriority:(double)p;//設(shè)置線程的優(yōu)先級(jí)
- (void)setName:(NSString*)n;//set方法
- (NSString*)name;//get方法
舉例:
thread.name=@"線程A";
NSThread->5.0線程間通訊和常用方法
線程間通信常用方法:
//在主線程執(zhí)行操作(從子線程回到主線程)(推薦)
- (void)performSelectorOnMainThread:(SEL)aSelector
withObject:(id)arg
waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector
onThread:(NSThread*)thr
withObject:(id)arg
waitUntilDone:(BOOL)wait;
GCD->1.0 GCD簡介和使用
GCD 的優(yōu)勢(shì):
GCD是蘋果公司為多核的并行運(yùn)算提出的解決方案
GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核、四核)
GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程晴氨、調(diào)度任務(wù)康嘉、銷毀線程)
程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼
任務(wù)的執(zhí)行:同步
//queue:隊(duì)列block:任務(wù)
dispatch_sync(dispatch_queue_tqueue,dispatch_block_tblock);
任務(wù)的執(zhí)行:異步
//queue:隊(duì)列block:任務(wù)
dispatch_async(dispatch_queue_tqueue,dispatch_block_tblock);
//在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行籽前,而且它后面的任務(wù)等它執(zhí)行完成之后才會(huì)執(zhí)行
dispatch_barrier_async(dispatch_queue_tqueue,dispatch_block_tblock);
【區(qū)別】同步 & 異步:同步和異步?jīng)Q定了要不要開啟新的線程
-同步:只能在當(dāng)前線程中執(zhí)行任務(wù)亭珍,不具備開啟新線程的能力
-異步:可以在新的線程中執(zhí)行任務(wù)敷钾,具備開啟新線程的能力
【區(qū)別】并發(fā) & 串行:并發(fā)和串行決定了任務(wù)的執(zhí)行方式
-并發(fā):允許多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
-串行:一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
GCD的使用 - 隊(duì)列
并發(fā)隊(duì)列
-可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
-并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
串行隊(duì)列
-讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后肄梨,再執(zhí)行下一個(gè)任務(wù))
release
-凡是函數(shù)名種帶有create\copy\new\retain等字眼,都應(yīng)該在不需要使用這個(gè)數(shù)據(jù)的時(shí)候進(jìn)行release
- GCD的數(shù)據(jù)類型在ARC環(huán)境下不需要再做release
dispatch_release(queue);//非ARC需要釋放手動(dòng)創(chuàng)建的隊(duì)列
- CF(Core Foundation)的數(shù)據(jù)類型在ARC環(huán)境下還是需要再做release
創(chuàng)建隊(duì)列 - 并發(fā)隊(duì)列
方式1 - 手動(dòng)創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_create(
constchar *label,//隊(duì)列名稱
dispatch_queue_attr_tattr//隊(duì)列的類型
);
// 1.創(chuàng)建并發(fā)隊(duì)列DISPATCH_QUEUE_CONCURRENT (并發(fā))
dispatch_queue_t queue = dispatch_queue_create(“TD", DISPATCH_QUEUE_CONCURRENT);
// 2.非ARC需要釋放手動(dòng)創(chuàng)建的隊(duì)列
dispatch_release(queue);
方式2 - 獲取全局并發(fā)隊(duì)列:(GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列阻荒,供整個(gè)應(yīng)用使用,可以無需手動(dòng)創(chuàng)建
#define DISPATCH_QUEUE_PRIORITY_HIGH2//高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT0//默認(rèn)(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)//低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN//后臺(tái)
dispatch_get_global_queue(
longidentifier,//隊(duì)列的優(yōu)先級(jí)
unsignedlong flags//此參數(shù)暫時(shí)無用众羡,用0即可
);
//獲取全局并發(fā)隊(duì)列
dispatch_queue_tqueue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
#pragma mark -同步函數(shù)+并發(fā)隊(duì)列:不會(huì)開啟新的線程侨赡,在當(dāng)前線程執(zhí)行任務(wù)(主線程),順序執(zhí)行粱侣,并發(fā)隊(duì)列失去了并發(fā)的功能
- (void)syncConcurrent {
NSLog(@"同步并發(fā)----- begin");
// 1.獲得全局的并發(fā)隊(duì)列
dispatch_queue_tqueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 2.將任務(wù)加入隊(duì)列
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThreadcurrentThread]);
});
NSLog(@"同步并發(fā)----- end");
}
#pragma mark -寫法2
- (void)concurrentSync {
// 1.創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_tconCurrentQueue =
dispatch_queue_create("TD", DISPATCH_QUEUE_CONCURRENT);
// 2.創(chuàng)建任務(wù)
void(^task1)() = ^() {
NSLog(@"---task1---%@", [NSThreadcurrentThread]);
};
void(^task2)() = ^() {
NSLog(@"---task2---%@", [NSThreadcurrentThread]);
};
void(^task3)() = ^() {
NSLog(@"---task3---%@", [NSThreadcurrentThread]);
};
// 3.將同步任務(wù)添加到并發(fā)隊(duì)列中
dispatch_sync(conCurrentQueue, task1);
dispatch_sync(conCurrentQueue, task2);
dispatch_sync(conCurrentQueue, task3);
}
#pragma mark -異步函數(shù)+并發(fā)隊(duì)列:可以同時(shí)開啟多條線程羊壹,在當(dāng)前線程執(zhí)行任務(wù)(主線程),無序執(zhí)行(按照任務(wù)添加到隊(duì)列中的順序被調(diào)度)齐婴,線程條數(shù)具體由`可調(diào)度線程池/底層線程池`來決定
- (void)asyncConcurrent {
NSLog(@"異步并發(fā)----- begin");
// 1.獲得全局的并發(fā)隊(duì)列
dispatch_queue_tqueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
// 2.將任務(wù)加入隊(duì)列
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThreadcurrentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThreadcurrentThread]);
});
NSLog(@"異步并發(fā)----- begin");
}
#pragma mark -寫法2
- (void)concurrentAsync {
// 1.創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_tconCurrentQueue =
dispatch_queue_create("TD", DISPATCH_QUEUE_CONCURRENT);
// 2.創(chuàng)建任務(wù)
void(^task1)() = ^() {
NSLog(@"---task1---%@", [NSThreadcurrentThread]);
};
void(^task2)() = ^() {
NSLog(@"---task2---%@", [NSThreadcurrentThread]);
};
void(^task3)() = ^() {
NSLog(@"---task3---%@", [NSThreadcurrentThread]);
};
// 3.將異步任務(wù)添加到并發(fā)隊(duì)列中
dispatch_async(conCurrentQueue, task1);
dispatch_async(conCurrentQueue, task2);
dispatch_async(conCurrentQueue, task3);
}
創(chuàng)建隊(duì)列-隊(duì)列
//1.創(chuàng)建串行隊(duì)列
//方式1:DISPATCH_QUEUE_SERIAL (串行)
dispatch_queue_t queue = dispatch_queue_create(“TD", DISPATCH_QUEUE_SERIAL);
//方式2:傳NULL
dispatch_queue_t queue = dispatch_queue_create(“TD",NULL);
// 2.非ARC需要釋放手動(dòng)創(chuàng)建的隊(duì)列
dispatch_release(queue);
串行隊(duì)列油猫,異步任務(wù),在多線程中柠偶,是斯坦福大學(xué)最推薦的一種多線程方式
優(yōu)點(diǎn):將任務(wù)放在其他線程中工作情妖,每個(gè)任務(wù)順序執(zhí)行,便于調(diào)試
缺點(diǎn):并發(fā)能力不強(qiáng)嚣州,最多只能使用一條線程鲫售!
同步函數(shù) + 并發(fā)隊(duì)列:不會(huì)開啟新的線程,在當(dāng)前線程執(zhí)行任務(wù)(主線程)该肴,順序執(zhí)行情竹,并發(fā)隊(duì)列失去了并發(fā)的功能
#異步函數(shù) + 并發(fā)隊(duì)列:可以同時(shí)開啟多條線程,在當(dāng)前線程執(zhí)行任務(wù)(主線程)匀哄,無序執(zhí)行(按照任務(wù)添加到隊(duì)列中的順序被調(diào)度)秦效,線程條數(shù)具體由可調(diào)度線程池/底層線程池來決定
(1)如果異步任務(wù)前面有同步任務(wù):就會(huì)先執(zhí)行同步任務(wù)同步任務(wù)是按順序執(zhí)行的任務(wù)等他執(zhí)行完了才會(huì)執(zhí)行并行中的異步任務(wù)(可以做到阻塞 控制任務(wù)的執(zhí)行順序)
(2)如果異步任務(wù)后面有同步任務(wù):兩個(gè)任務(wù)會(huì)并行(同時(shí))執(zhí)行
同步函數(shù) + 串行隊(duì)列:不會(huì)開啟新的線程,在當(dāng)前線程執(zhí)行任務(wù)(主線程)涎嚼,任務(wù)是串行的(順序執(zhí)行)
異步函數(shù) + 串行隊(duì)列:會(huì)開啟新的線程阱州,在子線程執(zhí)行任務(wù),任務(wù)是串行的(順序執(zhí)行)法梯,只開一條線程
串行隊(duì)列中的任務(wù)都是按順序執(zhí)行:
異步函數(shù) + 主隊(duì)列:不會(huì)開啟新的線程苔货,在當(dāng)前線程執(zhí)行任務(wù)(主線程),任務(wù)是串行的(順序執(zhí)行)立哑,只開一條線程(適合處理 UI 或者是 UI事件)
同步函數(shù) + 主隊(duì)列:不會(huì)開啟新的線程夜惭,會(huì)出現(xiàn)"死等",可能導(dǎo)致主線程卡死
【區(qū)別】同步 & 異步:同步和異步?jīng)Q定了要不要開啟新的線程
-同步:只能在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
-異步:可以在新的線程中執(zhí)行任務(wù)铛绰,具備開啟新線程的能力
【區(qū)別】并發(fā) & 串行:并發(fā)和串行決定了任務(wù)的執(zhí)行方式
-并發(fā):允許多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
-串行:一個(gè)任務(wù)執(zhí)行完畢后诈茧,再執(zhí)行下一個(gè)任務(wù)
同步函數(shù):無論是什么隊(duì)列都不會(huì)開啟線程
(1)并發(fā)隊(duì)列:不會(huì)開線程
(2)串行隊(duì)列:不會(huì)開線程
異步函數(shù):具備開啟線程的能力(但不一定會(huì)開線程 ),開啟幾條線程由隊(duì)列決定
(1)并發(fā)隊(duì)列:能開啟N條線程
(2)串行隊(duì)列:開啟1條線程
Touch ID定制Demo
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = <#String explaining why app needs authentication#>;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
// User authenticated successfully, take appropriate action
dispatch_async(dispatch_get_main_queue(), ^{
// write all your code here
});
} else {
// User did not authenticate successfully, look at error and take appropriate action
switch (error.code) {
case LAErrorAuthenticationFailed:
NSLog(@"Authentication Failed");
break;
case LAErrorUserCancel:
NSLog(@"User pressed Cancel button");
break;
case LAErrorUserFallback:
NSLog(@"User pressed \"Enter Password\"");
break;
default:
NSLog(@"Touch ID is not configured");
break;
}
NSLog(@"Authentication Fails");
}
}];
} else {
// Could not evaluate policy; look at authError and present an appropriate message to user
}
iOS ---沙盒
Documents目錄
保存應(yīng)用程序運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù)捂掰,Itunes會(huì)自動(dòng)備份該目錄
Library目錄
存儲(chǔ)程序的默認(rèn)設(shè)置和其他狀態(tài)信息敢会,Itunes會(huì)自動(dòng)備份該目錄
tmp目錄
保存應(yīng)用運(yùn)行時(shí)所需要的臨時(shí)數(shù)據(jù)曾沈,使用完畢后在將相應(yīng)的文件從該目錄刪除。
獲取沙盒路徑
NSString *path = NSHomeDirectory();
獲取沙盒下文件目錄的路徑
有三種獲取方法:
1.拼接字符串:
NSString *Documents = [path stringByAppendingString:@"/Documents"];
2.拼接路徑
NSString *Documents2 = [path stringByAppendingPathComponent:@"Documents"];
3.系統(tǒng)提供的獲取沙盒下目錄路徑的方法
NSString *Documents3 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO) firstObject];
//NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO) 方法返回值為只有一個(gè)元素的數(shù)組鸥昏,所以去第一個(gè)元素
對(duì)于其他兩個(gè)文件路徑的獲取方式都一樣塞俱,系統(tǒng)提供的方法有些區(qū)別
NSString *library3 = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
//對(duì)于Library文件獲取路徑方法,只是參數(shù)有些不一樣
//獲取library下的caches
NSString *cachesStr = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
獲取tmp文件夾路徑(系統(tǒng)提供的方法)
NSString *tmpStr = NSTemporaryDirectory();
獲取程序包路徑
NSString *appPath = [NSBundle mainBundle].resourcePath;
獲取程序包內(nèi)種的一個(gè)圖片資源(apple.png)路徑
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"png"];
簡單對(duì)象的讀寫(I/O)操作
簡單對(duì)象:字符串互广,數(shù)組敛腌,字典卧土,data
字符串存儲(chǔ)
//獲取存儲(chǔ)的目錄
NSString *str = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//在沙盒文件夾下的Documents內(nèi)創(chuàng)建.txt文件
NSString *newPath = [str stringByAppendingPathComponent:@"text.txt"];
//存入內(nèi)容
NSString *name = @"藍(lán)歐科技, nihao";
[name writeToFile:newPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
字符串讀取
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *newPath = [path stringByAppendingString:@"/text.txt"];
NSString *string = [NSString stringWithContentsOfFile:newPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"%@", string);
數(shù)組存儲(chǔ)
[nameArr writeToFile:newPath atomically:YES];
數(shù)組讀取
NSArray *array = [NSArray arrayWithContentsOfFile:newPath];
字典存儲(chǔ)
[dict writeToFile:newPath atomically:YES];
字典讀取
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:newPath];
NSData類型存儲(chǔ)
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
//寫入文件
[data writeToFile:dataPath atomically:YES];
NSData讀取
//獲取路徑
NSData *data = [NSData dataWithContentsOfFile:dataPath];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
圖片存儲(chǔ)//將圖片轉(zhuǎn)成NSData類型在存儲(chǔ)
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//在沙盒問價(jià)下面創(chuàng)建一個(gè)文件
NSString *newPath = [path stringByAppendingPathComponent:@"image.png"];
//需要存儲(chǔ)的圖片
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"tu.jpg"], 1.0);
//創(chuàng)建文件并存儲(chǔ)
[imageData writeToFile:newPath atomically:YES];
圖片讀取
//獲取沙盒地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//獲取圖片data地址
NSString *newPath = [path stringByAppendingPathComponent:@"image.png"];
//獲取data
NSData *data = [NSData dataWithContentsOfFile:newPath];
//獲取圖片
UIImage *image = [UIImage imageWithData:data];
//添加imageView
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 200, 150, 150)];
imageView.image = image;
[self.view addSubview:imageView];
通過文件管理器來操作對(duì)象
創(chuàng)建對(duì)象
NSString *string = @"hello nihao";
//根據(jù)字符串創(chuàng)建data
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
創(chuàng)建文件管理器
NSFileManager *fileManager = [[NSFileManager alloc] init];
存儲(chǔ)對(duì)象//向目標(biāo)文件寫入信息
BOOL save = [fileManager createFileAtPath:[[self documentPath] stringByAppendingPathComponent:@"studenttt.plist"] contents:data attributes:nil];
//注:[self documentPath]是獲取Documents路徑
//獲取Documents路徑
- (NSString *)documentPath {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
}
讀取對(duì)象
NSData *mData = [fileManager contentsAtPath:[[self documentPath] stringByAppendingPathComponent:@"studenttt.plist"]];
NSString *mStr = [[NSString alloc] initWithData:mData encoding:NSUTF8StringEncoding];
復(fù)雜對(duì)象的讀寫---歸檔和反歸檔
1.首先惫皱,復(fù)雜對(duì)象所屬的類要遵循協(xié)議
//Person.h
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *gender;
@property (nonatomic, assign) NSInteger age;
@end
2.其次,實(shí)現(xiàn)協(xié)議中的兩個(gè)方法
-(void)encodeWithCoder:(NSCoder *)aCoder;
-(instancetype)initWithCoder:(NSCoder *)aDecoder
//Person.m
@implementation Person
//當(dāng)對(duì)象進(jìn)行歸檔操作的時(shí)候尤莺,會(huì)自動(dòng)調(diào)用這個(gè)方法
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.gender forKey:@"gender"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
//當(dāng)對(duì)象進(jìn)行反歸檔的時(shí)候會(huì)調(diào)用
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.gender = [aDecoder decodeObjectForKey:@"gender"];
}
return self;
}
@end
歸檔 ——NSKeyedArchiver
Person *person = [[Person alloc] init];
person.name = @"小明";
person.age = 23;
person.gender = @"男";
//進(jìn)行歸檔操作
//1.創(chuàng)建一個(gè)NSmutableData,用來存儲(chǔ)歸檔后的數(shù)據(jù)
NSMutableData *mData = [[NSMutableData alloc] init];
//2.創(chuàng)建歸檔器
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mData];
//進(jìn)行歸檔
[archiver encodeObject:person forKey:@"person"];
//歸檔結(jié)束
[archiver finishEncoding];
//存到沙盒的文件夾中
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *newPath = [path stringByAppendingPathComponent:@"guidang.plist"];
//存儲(chǔ)data
[mData writeToFile:newPath atomically:YES];
反歸檔 ——NSKeyedUnarchiver
//獲取路徑
NSString * newPath = [[self documentPath] stringByAppendingPathComponent:@"guidang.plist"];
//取出數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfFile:newPath];
//創(chuàng)建反歸檔器
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person = [unArchiver decodeObjectForKey:@"person"];
//反歸檔結(jié)束
[unArchiver finishDecoding];
NSLog(@"name : %@ age : %ld gender : %@", person.name, person.age, person.gender);
iOS語言本地化/國際化
應(yīng)用名稱本地化/國際化
InfoPlist.strings
CFBundleDisplayName = "國際化App名稱";
代碼中字符串的本地化
Localizable.stirings
// NSLocalizedString(key, comment) 本質(zhì)
// NSlocalizeString 第一個(gè)參數(shù)是內(nèi)容,根據(jù)第一個(gè)參數(shù)去對(duì)應(yīng)語言的文件中取對(duì)應(yīng)的字符串旅敷,第二個(gè)參數(shù)將會(huì)轉(zhuǎn)化為字符串文件里的注釋,可以傳nil颤霎,也可以傳空字符串@""媳谁。
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
Targets:
Build Settings
Search Paths
Header Search Paths
NSNotification
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(notifyUrlScheme:) name:kNotifyUrlScheme object:nil];
NSNotification *notice = [NSNotification notificationWithName:kNotifyUrlScheme ?object:self userInfo:dic];
[[NSNotificationCenter defaultCenter] postNotification:notice];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self name:kNotifyUrlScheme object:nil];
Notification
Local Notification
remote notifications
- (void)application:(UIApplication *)application?didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userinfo {
}
atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。
assign
對(duì)基礎(chǔ)數(shù)據(jù)類型 (NSInteger友酱,CGFloat)和C數(shù)據(jù)類型(int, float, double, char)等等晴音。
此標(biāo)記說明設(shè)置器直接進(jìn)行賦值,這也是默認(rèn)值缔杉。
retain
對(duì)其他NSObject和其子類對(duì)參數(shù)進(jìn)行release舊值锤躁,再retain新值
copy
對(duì)NSString 它指出,在賦值時(shí)使用傳入值的一份拷貝或详。
也就是說系羞,retain 是指針拷貝,copy 是內(nèi)容拷貝
weak 和 strong 屬性只有在你打開ARC時(shí)才會(huì)被要求使用霸琴,這時(shí)你是不能使用retain release autorelease 操作的椒振,因?yàn)锳RC會(huì)自動(dòng)為你做好這些操作,但是你需要在對(duì)象屬性上使用weak 和strong,其中strong就相當(dāng)于retain屬性梧乘,而weak相當(dāng)于assign澎迎。
ARC的重點(diǎn):
它是Compile-time的技術(shù),并不是在runtime用thread去處理
開發(fā)者不能再直接使用retain,release,autorelease选调,改由compiler幫你寫這些代碼夹供。
所有的property不再使用retain,assign而改用strong,weak取代。
NSAutoreleasePool也要改用特有的@autoreleasepool{}來取代
ARC的工作原理:
在你編譯程序時(shí)学歧,將內(nèi)存操作的代碼(retain罩引,release或autorelease)自動(dòng)添加到需要的位置。即底層上使用和Manual Reference Counting(手工引用計(jì)數(shù))一樣的內(nèi)存管理機(jī)制枝笨,但由于是自動(dòng)幫你在編譯時(shí)添加內(nèi)存操作的代碼袁铐,從而簡化了編程的工作揭蜒。
第31條 在dealloc方法中只釋放引用并解除監(jiān)聽
要點(diǎn)
? 在dealloc方法里,應(yīng)該做的事情就是釋放指向其他對(duì)象的引用剔桨,并取消原來訂閱的“鍵值觀測(cè)”(KVO)或NSNotificationCenter等通知屉更,不要做其他事情。
? 如果對(duì)象持有文件描述符等系統(tǒng)資源洒缀,那么應(yīng)該專門寫一個(gè)方法來釋放此種資源瑰谜。這樣的類要和其使用者約定:用完資源后必須調(diào)用close方法。
? 執(zhí)行異步任務(wù)的方法不應(yīng)該在dealloc里調(diào)用树绩;只能在正常狀態(tài)下執(zhí)行的那些方法也不應(yīng)在dealloc里調(diào)用萨脑,因?yàn)榇藭r(shí)對(duì)象已處于正在回收的狀態(tài)了。
第36條 不要使用retainCount
要點(diǎn)
? 對(duì)象的保留計(jì)數(shù)看似有用饺饭,實(shí)則不然渤早,因?yàn)槿魏谓o定時(shí)間點(diǎn)上的“絕對(duì)保留計(jì)數(shù)”(absolute retain count對(duì)象生命期的全貌。
引入ARC之后瘫俊,retainCount方法就正式廢止了鹊杖,在ARC‰o調(diào)用該方法會(huì)導(dǎo)致編譯器報(bào)錯(cuò)。
Other Framework
1.ZXingObjC---二次元コード
- (IBAction)updatePressed:(id)sender {
[self.textView resignFirstResponder];
NSString *data = self.textView.text;
if (data == 0) return;
ZXMultiFormatWriter *writer = [[ZXMultiFormatWriter alloc] init];
ZXBitMatrix *result = [writer encode:data
format:kBarcodeFormatQRCode
width:self.imageView.frame.size.width
height:self.imageView.frame.size.width
error:nil];
if (result) {
ZXImage *image = [ZXImage imageWithMatrix:result];
self.imageView.image = [UIImage imageWithCGImage:image.cgimage];
} else {
self.imageView.image = nil;
}
}
Object-C
使用synchronized方法實(shí)現(xiàn):
staticidobj = nil;
+(instancetype)shareInstance
{
@synchronized(self) {
if(!obj) {
obj = [[SingletonObj alloc] init];
}
}
returnobj;
}
使用dispatch_once方法實(shí)現(xiàn):
static id obj = nil;
+(instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
obj = [[SingletonObj alloc] init];
});
return obj;
}
數(shù)據(jù)類型
ObjC支持的數(shù)據(jù)類型包括:基本類型扛芽、構(gòu)造類型和指針類型骂蓖。其中,基本類型包括:整型川尖、字符型登下、浮點(diǎn)型和枚舉型;構(gòu)造類型包括:數(shù)組類型空厌、結(jié)構(gòu)體類型和共用體類型庐船;而指針類型是ObjC中最重要的類型。
整型
short int,int,long int,long long,unsigned
int 與 NSInteger, bool 與 BOOL, float 與 CGFloat
NSValue
另外NSNumber支持和NSString一樣的@符號(hào)簡寫
NSArray
字符型
char,
NSString
http://blogios.stack3.net/archives/309
検索
NSString#rangeOfStringメソッドを使います嘲更。戻り値はNSRange構(gòu)造體です筐钟。
NSRange#location 見つかった位置のインデックス。見つからなかった時(shí)はNSNotFound
NSRange#length 見つかった文字列の長さ
NSRange range;
range = [@"string" rangeOfString:@"ring"];
// --> range.location = 2; range.length = 4;
range = [@"string" rangeOfString:@"abc"];
// --> range.location = NSNotFound; range.length = 0;
大文字小文字區(qū)別なし赋朦。
range = [@"string" rangeOfString:@"NG" options:NSCaseInsensitiveSearch];
// --> range.location = 4; range.length = 2;
後ろから検索篓冲。
range = [@"abcabcabc" rangeOfString:@"abc" options:NSBackwardsSearch];
// --> range.location = 6; range.length = 3;
複數(shù)のオプションをORで指定することもできます。以下は宠哄、大文字小文字區(qū)別なし壹将、かつ、後ろから検索毛嫉。
range = [@"abcabcabc" rangeOfString:@"ABC" options:NSCaseInsensitiveSearch|NSBackwardsSearch];
// --> range.location = 6; range.length = 3;
optionsに0を指定すると條件指定なし诽俯。単なるrangeOfStringと同じです。
range = [@"abcabcabc" rangeOfString:@"ABC" options:0];
// --> range.location = NSNotFound; range.length = 0;
正規(guī)表現(xiàn)による検索承粤。
range = [@"? abc" rangeOfString:@"\w+" options:NSRegularExpressionSearch];
// --> range.location = 2; range.length = 3;
範(fàn)囲を指定して検索暴区。
range = [@"abcabc" rangeOfString:@"abc" options:0 range:NSMakeRange(3, 3)];
// --> range.location = 3; range.length = 3;
range = [@"abcabc" rangeOfString:@"ABC" options:NSCaseInsensitiveSearch range:NSMakeRange(3, 3)];
// --> range.location = 3; range.length = 3;
置換
置換はメソッド名が長いです???
string = [@"string" stringByReplacingOccurrencesOfString:@"ring" withString:@"and"];
// --> @"stand"
また闯团、見つかった文字は全部置換されることに注意が必要です。
string = [@"stringring" stringByReplacingOccurrencesOfString:@"ring" withString:@"and"];
// --> @"standand"
最初に見つかった文字だけ置換したい場(chǎng)合仙粱。
string = @"stringring";
NSRange range = [string rangeOfString:@"ring"];
if (range.location != NSNotFound) {
string = [string stringByReplacingCharactersInRange:range withString:@"and"];
// --> @"standring"
}
文字列の連結(jié)
NSString *string = @"abc";
string = [string stringByAppendingString:@"def"];
// string --> @"abcdef"
もちろん変數(shù)に代入にしなくても直接呼び出せます房交。
string = [@"abc" stringByAppendingString:@"def"];
STAssertEqualObjects(string, @"abcdef", nil);
NSMutableStringを使う場(chǎng)合
NSMutableString *mutableString = [NSMutableString stringWithString:@"abc"];
// こういう書き方もできる
// mutableString = [@"abc" mutableCopy];
[mutableString appendString:@"def"];
// string --> @"abcdef"
數(shù)値などを文字列に埋めたい時(shí)は、フォーマットを使う伐割。
string = @"abc";
string = [string stringByAppendingFormat:@"%d", 100];
// string --> @"abc100"
mutableString = [NSMutableString stringWithString:@"abc"];
[mutableString appendFormat:@"%d", 100];
// string --> @"abc100"
あまり使わないと思いますが候味、こういうのもあります。
string = @"abc";
string = [string stringByPaddingToLength:6 withString:@"x" startingAtIndex:0];
// string --> @"abcxxx"
文字列は第1引數(shù)Lengthの長さになります隔心。
文字列がLengthより短い場(chǎng)合は末尾を第2引數(shù)のStringで埋めます白群。
文字列が第2引數(shù)の文字列のどの位置から連結(jié)するかを第3引數(shù)で決定します。
第3引數(shù)がわかりづらいとおもうのですが济炎、たとえばこういうことです川抡。
string = @"abc";
string = [string stringByPaddingToLength:9 withString:@"efg" startingAtIndex:2];
// string -> @"abcgefgef"
文字列の長さを9文字にして辐真、@”efg”のindex:2つまり@”g”から連結(jié)をはじめ须尚、次は@”ef”と連結(jié)するのを繰りかえすことになります。
文字列の分解
カンマ區(qū)切りの文字列を分解侍咱。
NSString *string = @"Apple,Orange,Grape";
NSArray *array = [string componentsSeparatedByString:@","];
// array --> @[@"Apple", @"Orange", @"Grape"];
カンマ+スペース區(qū)切りの文字列を分解
string = @"Apple, Orange, Grape";
array = [string componentsSeparatedByString:@", "];
// array --> @[@"Apple", @"Orange", @"Grape"]
空白(半角スペース耐床、全角スペース)で區(qū)切られているものを分解。こういう場(chǎng)面ではNSCharacterSetを使うと良い楔脯。
string = @"Apple Orange Grape";
array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// array --> @[@"Apple", @"Orange", @"Grape"]
指定インデックスから切り取る撩轰。
string = [@"abcdef" substringFromIndex:3];
// string --> @"def"
指定インデックスより前までを切り取る。指定インデックスは含まない昧廷。
string = [@"abcdef" substringToIndex:3];
// string --> @"abc"
指定範(fàn)囲を切り取る堪嫂。
string = [@"abcdef" substringWithRange:NSMakeRange(2, 2)];
// string --> @"cd"
NSMutableString好比一個(gè)字符串鏈表,
- \- (void)appendString:(NSString *)aString;
+ 拼接aString到最后面
- \- (void)appendFormat:(NSString *)format, ...;
+ 拼接一段格式化字符串到最后面
- (void)deleteCharactersInRange:(NSRange)range;
刪除range范圍內(nèi)的字符串
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc;
在loc這個(gè)位置中插入aString
NSUserDefault用法
方法很簡單,一行代碼就可以搞定
//保存
- (void)saveValue:(NSString *)value forKey:(NSString *)key
{
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
}
//讀取
- (void)readValueforKey:(NSString *)key
{
[[NSUserDefaults standardUserDefaults] objectForKey:key];
}
[[NSUserDefaults standardUserDefaults] setValue:version forKey:@"newfeatures"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSString *newUserAgent = [NSString stringWithFormat:@"KuronekoyamatoOfficialApp/%@ %@", aplversion, userAgent];
NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:newUserAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dic];
(lldb) po dic
{
UserAgent = "KuronekoyamatoOfficialApp/2.26.0 Mozilla/5.0 (iPhone; CPU iPhone OS 9_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E230”;
}
注意
NSUserDefault只能保存特定類型的對(duì)象:NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary木柬。如果想要存儲(chǔ)其它類型皆串,需要將打包成NSData類型。
當(dāng)應(yīng)用第一次設(shè)置某項(xiàng)用戶偏好設(shè)置的值時(shí)眉枕,相應(yīng)的值會(huì)通過指定的鍵加入應(yīng)用域恶复。當(dāng)通過NSUserDefaults獲取某項(xiàng)用戶偏好設(shè)置的值時(shí),NSUserDefaults會(huì)先在應(yīng)用域中查找速挑,如果找到了值谤牡,NSUserDefaults就會(huì)返回這個(gè)值。如果沒有找到姥宝,NSUserDefaults就會(huì)在注冊(cè)域中查找并返回默認(rèn)值翅萤。
NSUserDefaults從上到下透過域的層級(jí)尋找正確的值,不同的域有不同的功能腊满,有些域是可持久的套么,有些域則不行流纹。
應(yīng)用域(application domain)是最重要的域,它存儲(chǔ)著你app通過NSUserDefaults set...forKey添加的設(shè)置违诗。
注冊(cè)域(registration domain)僅有較低的優(yōu)先權(quán)漱凝,只有在應(yīng)用域沒有找到值時(shí)才從注冊(cè)域去尋找。
全局域(global domain)則存儲(chǔ)著系統(tǒng)的設(shè)置
語言域(language-specific domains)則包括地區(qū)诸迟、日期等
參數(shù)域( argument domain)有最高優(yōu)先權(quán)
Protocol協(xié)議
@protocol?ProtocolDelegate?//?必須實(shí)現(xiàn)的方法
@required
-?(void)error;
//?可選實(shí)現(xiàn)的方法
@optional
-?(void)other;
-?(void)other2;
-?(void)other3;
@end
#import
@interface ASStudent : NSObject
{
NSString* name;//ios當(dāng)中 對(duì)象都是在堆上分配的茸炒,所以都是指針
@public
unsigned int age;
@private
NSString* sid;//
}
+(void)print; // + 代表方法為 類方法; void為返回值類型阵苇, print為簽名
-(void)setName:(NSString*)aName;// - 代表方法為 實(shí)例方法壁公; void為返回值類型,setName: 為 簽名 :也屬于簽名部分绅项; NSString* 為形參類型紊册, aName為形參
-(NSString*)name;
//-(void)name;//error 實(shí)例方法簽名不能相同 這個(gè)和上面都是 name
-(void)name:(int)aname;// 簽名部分為 name: 包含冒號(hào)部分所以不算相同
+(void)name; //true 類方法和 實(shí)例方法簽名可以相同方法簽名不能一樣,不支持重載
//在同一個(gè)類內(nèi)方法不能重載快耿,即方法的簽名不能完全一樣囊陡;但是類方法和實(shí)例方法簽名可以相同
//方法的簽名 和 參數(shù)類型、參數(shù)名稱無關(guān)
//方法簽名和方法的返回值類型無關(guān)掀亥;
@end
實(shí)現(xiàn):
#import "ASStudent.h"
@implementation ASStudent
-(NSString*)name{
return name;
}
-(void)setName:(NSString *)aName{
name = aName;
}
+(void)print{
NSLog(@"類方法");
}
//實(shí)例方法可以直接引用類的實(shí)例變量和其他實(shí)例方法
//類的方法都是public的撞反,沒有protected 和 private方法 ,但是如果一個(gè)方法 只是出現(xiàn)在類的方法里面搪花,沒有出現(xiàn)在類的聲明里遏片,name這個(gè)方法可以認(rèn)為是私有的!
@end
.h文件中@interface指令用來標(biāo)識(shí)文件的接口代碼的起始位置撮竿,而@end指令標(biāo)示該段的結(jié)束位置吮便。在.m文件中,@implementation指令用來標(biāo)識(shí)實(shí)現(xiàn)的起始位置幢踏,@end標(biāo)識(shí)結(jié)束位置
@interface用于定義類的公共接口髓需,通常,接口被稱為API(application programming interface)而真正使對(duì)象能夠運(yùn)行的代碼惑折,位于@implementation中授账。
當(dāng)我們要給一個(gè)Car類聲明一個(gè)發(fā)動(dòng)機(jī)屬性的時(shí)候,如果對(duì)外公開惨驶,則代碼為
文/xuyafei86(簡書作者)
原文鏈接:http://www.reibang.com/p/4f7dda4a5192
著作權(quán)歸作者所有白热,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡書作者”粗卜。如果不對(duì)外公開屋确,則在.m里的代碼為
關(guān)于Objective-C Runtime看我就夠了
http://www.reibang.com/p/f73ea068efd2
目通常采用工程文件設(shè)計(jì)結(jié)構(gòu)的例子
1.主目錄結(jié)構(gòu)
-ProjectDemo
--Features//模塊。包含各個(gè)模塊的Model,View,Controller,Manager
--categories//類目。包含各種類的分類
--Frameworks//系統(tǒng)框架攻臀。包含導(dǎo)入的系統(tǒng)的框架
--Helpers//幫助類焕数。包含網(wǎng)絡(luò),數(shù)據(jù)庫刨啸,歸檔堡赔,定位等操作類的封裝和實(shí)現(xiàn)
--Utilites//工具類,一些非對(duì)象的设联,而是類方法調(diào)用的類
--Vendors//第三方庫善已。部分需要修改或者不支持cocoapod的第三方的框架引入
--Config//配置。包含宏定義文件离例,全局配置文件换团,全局常量文件,顏色配置文件
--Resources//資源宫蛆。包含plist,image,html,bundle艘包,Localizable.strings等
--AppEntry//程序入口。包含AppDelegate,main.c,info.plist
-PAHealthTests
-PAHealthUITests
-Products// 系統(tǒng)自動(dòng)生成的.app所在文件夾
-Pods// 采用 CocoaPods 管理的第三方庫耀盗。
2.模塊目錄結(jié)構(gòu)
-- Features
---Base//MVC的基類或者通用類
----Models//數(shù)據(jù)模型
----Views//視圖
----Controllers//控制器
----Manager//store層的數(shù)據(jù)管理類
---Home
----Models
----Views
----Controllers
----Manager
---UserCenter
----Models
----Views
----Controllers
----Manager
---UserEntry
----Models
----Views
----Controllers
----Manager
---Payment
----Models
----Views
----Controllers
----Manager
…