基于
Objective-C基礎(chǔ)教程:1天玩轉(zhuǎn)Objective-C語法
【C基礎(chǔ)】#if剧蹂、if、#ifdef醒串、#if defined之間的區(qū)別
成員變量和屬性區(qū)別(@property那點事兒)
- Foundation/Foundation.h是 Foundation 框架的頭文件执桌,只要引入了它,就可以使用 Foundation 框架的所有功能了芜赌。這是一個核心庫
- 在 oc 中仰挣,字符串必須要加@,比如:@"hello world"
- Foundation框架中的很多數(shù)據(jù)類型名缠沈、變量名膘壶、函數(shù)名都是以NS開頭错蝴,喬布斯以此來紀(jì)念自己的公司 NeXTSTEP。
- 頭文件(.h)中定義的屬性和方法才能被外界訪問颓芭,類實現(xiàn)文件(.m)中定義的不能被外界訪問
- 類在.h文件和.m文件中都可以引入頭文件顷锰,區(qū)別是:在.h文件中引入頭文件,.h和.m文件都可以使用這個文件中的資源亡问;如果在.m文件引入頭文件官紫,.h文件不能使用該文件中的資源。
- 類定義舉例:
#import <Foundation/Foundation.h>
//引入頭文件
@interface Person : NSObject{
//聲明成員變量(很少用州藕,如果沒有聲明成員變量的話束世,可以省略大括號。)
}
//聲明屬性
@property int age;//基本數(shù)據(jù)類型(默認(rèn)會生成對應(yīng)的 set 和 get 方法床玻。另外會默認(rèn)生成對應(yīng)的成員變量_age);語法規(guī)定毁涉,不能初始化
@property (NSString*) str;//對象類型或引用類型
//聲明方法之類方法的創(chuàng)建(+號):
+(int)personWithA1:(float)a1 andA2:(NSString*)a2; //a1,a2分別代表兩個參數(shù)
//聲明方法之對象方法的創(chuàng)建(-號):
-(int)personWithA1:(float)a1 andA2:(NSString*)a2;
@end
- 類實現(xiàn)舉例:
#import "Person.h"
//引入頭文件
@implementation Person
//對聲明的方法進(jìn)行實現(xiàn)
@end
- 方法調(diào)用:(在 oc 中,準(zhǔn)確的說是“ 消息傳遞”)
//調(diào)用類方法
[Person personWithA1:2 andA2:@"類方法"];//通過類直接調(diào)用
//調(diào)用對象方法
Person * obj1=[[Person alloc]init];
[obj1 personWithA1:1 andA2:@"對象方法"];//通過類對象調(diào)用
- 點語法的底層實現(xiàn):(點語法锈死,簡單的理解薪丁,就是通過“.”的方式通過調(diào)用類中的set或get方法操作屬性。)重點在于如何改寫 set 和 get 方法馅精。
我們寫的代碼:
//.h 文件
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString * name;
@end
//.m 文件
#import "Person.h"
@implementation Person
@end
完整實現(xiàn):
//.h 文件
#import <Foundation/Foundation.h>
@interface Person : NSObject{
//編寫習(xí)慣严嗜,一般聲明成員變量的時候名字前面加“_”,同時也是為了和下邊聲明的name相對應(yīng)洲敢。
NSString * _name;
}
@property NSString * name;//通過這行代碼漫玄,OC底層隱式地聲明了兩個方法: set 和 get 方法
@end
//.m 文件
#import "Person.h"
@implementation Person
@synthesize name=_name;//將_name和name進(jìn)行綁定;對在.h文件聲明的get方法和set方法做實現(xiàn)
@end
- @propertye常用的修飾詞
nonatomic压彭、copy睦优、strong、assign壮不、weak汗盘、readwrite、readonly等
assign:用于基礎(chǔ)類型
copy:一般使用于字符串询一,再復(fù)制一份
weak:弱引用隐孽。
- 有個比喻:對于weak來說,就相當(dāng)于旁邊看放風(fēng)箏的人健蕊,他們只能用手指著你手里的風(fēng)箏菱阵,大喊著“風(fēng)箏風(fēng)箏”,他們只能和你一起欣賞風(fēng)箏缩功,而對于是不是繼續(xù)放風(fēng)箏的決定權(quán)在你晴及,如果你不在放風(fēng)箏了,那他們也只能“各回各家嫡锌,各找各媽”虑稼;
- 用OC的語言來表達(dá)琳钉,就是說用weak聲明的屬性雖然也可以訪問內(nèi)存,但是要在這塊內(nèi)存沒有釋放之前蛛倦,一旦這塊內(nèi)存被釋放之后歌懒,weak聲明的屬性將失去作用。
- 結(jié)構(gòu)體是值類型
在OC中struct是值類型的胰蝠,也就是說當(dāng)將一個結(jié)構(gòu)體賦值給另一個結(jié)構(gòu)體時歼培,二者實際上是相互獨(dú)立互不影響的。
直接訪問使用結(jié)構(gòu)體變量名.成員名茸塞,間接訪問使用(*結(jié)構(gòu)體指針名).成員名或者使用結(jié)構(gòu)體指針名->成員名躲庄。(總結(jié)來說,通過值訪問就用點符號钾虐,通過指針訪問就用->) - id 類型:可以認(rèn)為是任意類型
- SEL 類型:可以認(rèn)為是方法的指針類型噪窘。在 oc 中表示方法的編號
- 類別:
- 類別能夠在原有類的基礎(chǔ)上添加新的方法,而且還不會讓子類繼承效扫。
- 類擴(kuò)展能添加屬性和方法倔监,而類別只能添加方法
定義:
//Person+NewFuntion.h文件
#import "Person.h"
@interface Person (NewFuntion)
//添加方法
-(void)eat;
@end
實現(xiàn):
#import "Person+NewFuntion.h"
@implementation Person (NewFuntion)
//實現(xiàn)方法
-(void)eat{
NSLog(@"the person is eating!");
}
@end
使用:
#import <Foundation/Foundation.h>
#import "Person.h"
//一定要引入類別的接口文件,否則無法使用類別中添加的方法
#import "Person+NewFuntion.h"
int main(int argc, const char * argv[]) {
Person * person=[[Person alloc] init];
person.name=@"張三";
person.age=10;
[person run];
//調(diào)用類別中增加的eat方法
[person eat];
return 0;
}
- 協(xié)議:OC語言是單繼承多協(xié)議的語言(類型于 java 中的接口)
- 協(xié)議沒有父類(協(xié)議可以服從多個(>=0)協(xié)議(一般服從NSObject協(xié)議)
- 協(xié)議中不能定義變量(屬性)菌仁,只能定義方法浩习。
聲明一個協(xié)議:
@protocol ChildrenDelegate <NSObject>//協(xié)議聲明
-(void)eat;
@end
聲明一個符合此協(xié)議的對象屬性
@interface Children : NSObject
@property(nonatomic,weak)id<ChildrenDelegate>delegete;//一個實現(xiàn)此協(xié)議的任意類型的對象屬性
@end
真正實現(xiàn)此協(xié)議的類
@interface Nanny : NSObject<ChildrenDelegate>
@end
綜合使用:
int main(int argc, const char * argv[]) {
Children * child=[[Children alloc] init];
Nanny * nanny=[[Nanny alloc] init];
child.delegete=nanny;
if ([child.delegete respondsToSelector:@selector(eat)]) {
[child.delegete eat];
}
return 0;
}
@selector(eat)返回 eat 方法的編號,它是個 SEL 類型
- oc 中的數(shù)組對象济丘,鍵和值都必須是對象
- oc 中的數(shù)組谱秽,以如下形式初始化,必須以 nil 結(jié)束摹迷,代表數(shù)組的結(jié)尾疟赊。如:
NSArray * array1=[NSArray arrayWithObjects:@"0",@"1",@"2",@"3", nil];
- 在使用代碼塊的時候,對于全局變量峡碉,在塊內(nèi)是完全可操作的近哟。但是對于局部變量來說,在塊內(nèi)只能使用不能更改鲫寄。
如果試圖在塊內(nèi)更改局部變量的值吉执,程序會報錯,解決的方案是在聲明局部變量時添加_block關(guān)鍵字(注意是兩個“”) - nil, NULL, Nil 的區(qū)別:
nil定義某一實例對象為空值塔拳,如NSObject* obj = nil;
Nil 定義某一類為空鼠证,如Class someClass = Nil;
NULL 定義基本數(shù)據(jù)對象指針為空,如int *pointerToInt = NULL; char *pointerToChar = NULL; struct TreeNode *rootNode = NULL;
延申閱讀:
自動引用計數(shù):
https://blog.devtang.com/2016/07/30/ios-memory-management/
https://juejin.im/post/5a360d2d518825455f2f5df6結(jié)構(gòu)體是什么:https://zh.wikipedia.org/wiki/%E7%BB%93%E6%9E%84%E4%BD%93_(C%E8%AF%AD%E8%A8%80)
OC 中的結(jié)構(gòu)體及精彩評論:http://www.reibang.com/p/f1b2085c4179
c 語言中的指針:https://zhuanlan.zhihu.com/p/28041871
聲明一個指針類型的變量:
int *pInt = NULL
表示 pInt這個變量的值是數(shù)據(jù)或?qū)ο蟮闹羔樀刂返闹悼恳郑谶@里是 NULL,代表空指針适掰。
int 表示颂碧,pInt這個指針指向的數(shù)據(jù)或?qū)ο笫?int 類型的
使用的時候荠列,*pInt 表示pInt這個指針變量指向的數(shù)據(jù)或?qū)ο蟮闹怠?br> 使用的時候,@pInt 表示在內(nèi)存中存儲 pInt 這個值的內(nèi)存地址是多少载城。在這里pInt 本身就是一個指針值肌似,@pInt表示指向這個指針值的指針地址是多少。