1. NSString前面NS是NextSTEP的縮寫.
2.面向對象編程OOP (ObjectOrientedProgramming)
3.接口在程序里叫數據接口
在網絡里叫網絡接口
4.成員可見度定義:
@public大家的
@product受保護的
@private私有的
5.接口部分標志@interface@end一對
6.所有@的符號都是OC對C語言擴展的東西
7.
-(void)sayHi; -號代表實例方法.void是返回值類型.
+類方法.
8.
-號方法必須由實例對象來調用,+號方法必須由類來直接調用
9.NSLog=printfNSLog是C語言的函數
10.NSLog(@“sdfsdfsdf”);@后面叫字符串對象. %@替換對象的(替換進去的肯定是文字信息)
112015-01-22 16:32:33.758 HelloOC[618:303]HELLO, WORLD
618是進程號,303線程號
12.
類名大寫開頭
方法名和變量小寫開頭
13 #import導入oc基礎庫
14具有相同特征和行為的事物的抽象.類的定義
15所有的類都放在了全局區
alloc是把在全局去里的成員變量拷貝到堆里面一份
alloc所有的成員變量都有初值
16 void *p無類型指針
17id是typedefvoid *id叫泛型指針id可以保存任何類型的指針.
17不能簡單的改變2個變量的值,而作用域約束
如果想在外部去修改2個局部變量的值,必須拿到地址.
18->指向標示符
19父類:總類子類:分類的概念.而不是父親和兒子的概念(不是具體的實物)!
20給對象聲明空間的時候就賦初值
Person.h中:
@interface Person :NSObject
{
@public//如果下面沒給值,系統會自動初始化.
NSString *_name;
NSString *_gender;
NSString *_hobby;
NSString *_hobby1;
int _age;
}
- (id)init1;
@end
Person.m中:
- (id)init1
{
_age = 18;
_name = @"HAHAHA";
return self;
}
main.m中:
Person *p =[[Person alloc] init1];
[p eat];
可見度是約束(標示符)的訪問權限,指的是標示符符號的訪問權.
21
@public子類可見,外部也可見
@protected子類可見,外部不可見
@private子類不可見(不允許訪問),外部類不可見
子類可以繼承父類的private后的屬性,但是不能訪問.
private不光要保護內部數據的安全,也要保護外部能安全的使用.
22.在當前類中不允許方法名重復,在別的類可以定義一個跟這個方法同名的方法.
-(id)initWithName:(NSString *)name;init開頭是對創建對象和初始化的,不要隨便寫類名字開頭.如果init不是初始化的方法,Xcode會拒絕編譯.
初始化方法init只能調用一次.不能重復調用
- (void)setName:(NSString*)name setGender:(NSString *)gender
{
_name = name;
_gender = gender;
}
但是不能同時get2個屬性例如:
- (NSString*)getName: (NSString *)getGender
{
return self;
}這樣是錯誤的
如果不小心修改了Xcode的系統文件.
找到錯誤提示路徑,刪除里面所有東西,之后再Xcode中Product中選擇clean然后在重新編譯.
不能在main里面用super因為main類沒有父類.
對super發消息就是一個途徑,指向的從父類繼承的方法.
構造器用來創建對象的
重點:指派構造designated
initializer指派初始化方法.
(某個方法里面有super init那么這個方法就是指派構造化方法.(也是初始化入口)(也叫默認指派初始化方法)
類里面必須得有這么唯一一個指派初始化方法的入口
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
hobby:(NSString *)hobby
{
//self = [super init];
//if (self) {
//_name = name;
//_sex = sex;
//_hobby = hobby;
//}
//return self;
self = [self initWithName:name sex:sexhobby:hobby age:0];
return self;
}
指派初始化方法:
- (id)init
{
//self = [super init];
////如果self是有效指針(非空)
//if (self) {
//_name = @"小唐";
//_sex = @"男";
//_age = 40;
//}
self = [self initWithName:nil sex:nilhobby:nil age:0];
return self;
}
- (id)initWithName:(NSString*)name
{
self = [self initWithName:name sex:nil];
return self;
}
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
{
self = [self initWithName:name sex:sexhobby:nil];
return self;
}
- (id)initWithName:(NSString*)name
sex:(NSString *)sex
hobby:(NSString *)hobby
{
self = [self initWithName:name sex:sexhobby:hobby age:0];
return self;
}
-(id)initWithName:(NSString *)name
sex:(NSString *)sex
hobby:(NSString *)hobby
age:(NSInteger)age
{
self = [super init];
if (self) {
_name = name;
_sex = sex;
_hobby = hobby;
_age = age;
}
return self;
}
dealloc(銷毀)不允許手動調用,系統自動調用
MRC manual
reference count手動引用計數
ARCauto reference count系統自動掃描添加釋放內存.
-release()是引用計數器減1
-autorelease()自動釋放池.
-retain(引用,不會產生新的對象)對這個對象發送這個消息,引用計數器+1
[sturetainCount]輸出引用計數器的值
怎么把Xcode改成MRC
左鍵項目,然后搜matic找到objective-c
automatic reference counting改成no
alloc和retain的數量要等于release
便利構造器:
+
(id)personWithName:(NSString *)name//+開頭,類名開頭,返回的是id就是便利構造器
{
Person *person = [[Person alloc]initWithName:name];
return [person autorelease];
}
autorelease自動釋放池,什么時候釋放,是由系統控制的
//為什么釋放之后還是能打出來1:
Person *per = [PersonpersonWithName:@"小唐"];
NSLog(@"%lu",[per retainCount]);
[per release];
NSLog(@"%lu",[perretainCount]);//這個是野指針,雖然對象被釋放了,但是內存那塊沒被覆蓋,所以才能打出來1.
系統為了做優化,所以當retainCount為1的時候直接銷毀,不用再去—了.
- (void)release
{
if (1== self.retainCount) {
[self dealloc];
}
else {
self.retainCount--;
}
}
autorelease引用計數器延遲減1
成員變量是隨著對象消亡而消亡對象的消亡是在dealloc中,每個成員變量要在dealloc這釋放.
棧里面的東西是隨著函數的退出而消亡
當指針變量聲明周期結束前要release
settergetter方法,和便利構造器補全.
父對象要保證子對象在父對象的生命周期是安全的
比如myclass是父對象(_student這個指針指向的那個student就是子對象),里面有個Student*student這個student是子對象.(因為student是個指針也是個對象)
如何保證父對象里的子對象安全,對子對象retain.
為什么不能手動寫dealloc因為可能還有別人在用,釋放了的話就crash了
在.h中容易產生交叉導入,容易產生符號找不著的問題.
而真正的頭文件要在.m中導入.
父對象一定會強引用自己的子對象.(強引用,就是對引用計數器+1)
self是內部指向這個類的指針,stu是外部的指針
atomic(原子)原子化效率低,安全
一個類可以寫在不同的原文件中.(類目)
只能添加方法,不能添加成員變量.
@interface NSString(SayHi)給NSString添加一個SayHi
方法.
當兩個對象都同時要使用同一個字符串的時候,這個字符串類型要用NSMutableString
指針類型的作用:
1.做算術運算跳數的大小
2.間接尋址指向的類型.
NSString *p方便編譯器去檢查錯誤(為什么加指針符號
如果想讓類目訪問成員變量,必須在主類里顯示聲明.
isEqualToString比較兩個字符串對象是否相等\
怎么把數字轉換成字符串.
OC的數組會對每一個加進去的對象,引用計數器都會+1,然后釋放的時候,會自動減1.
//其實自動釋放池里就有一個數組
self只能初始化才能賦值,以后就不能變了.
字典存取不是連續的,是散列的,根據key所計算的下表(哈希算法)
字典以空指針結束.所以不能存空指針
//71 72 74
//26 27 30 313237
(集合)set無序集合.直接給一個對象,自動算hash.(當你需要知道一個對象是否在集合中) (集合和數組和對象不同,不能存重復對象)
假設hash重復了,就順延往下存,第二種就是往上跳10個.
第三種,做小集合,如果在這個小集合找到重復的了,就去另一個小集合找.
netsh winsock reset
super只能幫我們找到這個類從父類繼承過來的方法.
指針聲明周期結束之前要對它relase
局部變量在消亡時釋放?
成員變量在函數return時釋放?
id是泛型指針,(可以保存任意類型的指針)
添加到數組中得元素都會retain
遍歷構造器的好處:
1.工廠方法,工廠生產
2.我們不用關系它的釋放,因為返回回來的就是臨時對象!
加完斷點之后,在lldb中輸入po province打印這個對象.
子對象強引用父對象,形成內存空洞.都互相對對方引用計數器+ 1
嵌套引用(2個對象無法釋放)
類目
不能增加成員變量.(如果在類目中添加屬性,只有方法,沒有對應的成員變量).(類目不能訪問屬性創建的成員變量)
分類管理類
寫在不同的原文件中
額外添加相應方法
時間戳(1970年開始計算秒數):因為1970年Unix
NSDate存得的是標準時間,沒有時差.
//NSTimeZone *zone = [NSTimeZonetimeZoneWithName:@"America/Swift_Current"];
//[nmatter setTimeZone:zone];
//NSDate *sDate = [nmatterdateFromString:dateString];
//NSLog(@"%@", sDate);
OC的類目是為了防止java的過度繼承
OC中寫入延展是對類內部開放的,不讓外面類訪問(也就是java中得私有方法.)
有效的封裝不只是保證內部安全,還保障外部安全.
接口是對外服務的菜單
私有API方法是在延展里的,沒有在.h中聲明的
協議里的可選方法,(首先要確定這個方法實現了)
一個類可以遵守多個協議(協議是可以繼承的)
代理指針為什么用assign,不允許用retain為了防止父對象做子對象的代理時候,產生的循環應用.
(延展):把外面不需要的功能,放在類里面(高內聚)
(協議):每個類單獨管理,而不是兩個類互相有聯系(低耦合)
//alloc, copy, init產生的對象不需要釋放.(這3個單詞不能做字頭)
淺拷貝:父對象是同一個,子對象是不同的
深拷貝:父對象和子對象是不同的2對
父類指針指向了子類對象(多態) (目的:寫通用代碼);
setter和getter里面寫得先得判斷傳進來是不是以前的.
block就是一段代碼段,(訪問得用指針訪問) block就是一個對象,可以retain和copy