ios OC初學

OC源文件後綴名爲m,代表OC中最重要的一個機制:消息機制。
OC程序的入口與出口仍然是main函數
OC支持C中的所有關鍵字、運算符、控制語句、函數
OC語言完全兼容C語言

import即#include的增強版

同一個文件無論#import多少次,始終導入一次

NSLog是一個函數:

printf的增強版,想控制檯輸出信息;
NSLog(@”hello world”);
執行結果包括:
當前執行時間、程序名、進程編號、線程編號、程序執行信息
用法和printf相同、只不過前面要加@
NSLog的輸出是自動換行的,如果加上了\n,那麼NSLog的自動換行就會失效

字符串

OC中設計了一個更爲好用的用來存儲字符串的NSString類型
NSString類型的指針變量 專門用來存儲OC字符串的地址
使用NSLog輸出OC字符串的佔位符爲 %@

編輯、編譯、鏈接

cc -c xx.m

鏈接
cc xx.o
如果用到了框架
cc xx.0 - [framework framework_name]

新增的布爾型變量

BOOL只有兩個值:YES/NO
Boolean的值爲true/false

面向對象

類的聲明

@interface className : NSObject
{
  變量
}
@end

爲類定位屬性時,屬性的名詞必須以下劃線開頭
類的方法的聲明應寫在interface中
屬性不允許在聲明的時候初始化

類的實現

@implementation className
@end

類名的每一個單詞的開頭必須以大寫開頭
類方法的實現應寫在implementation中

類的實例化

對象中除了成員變量外,還有一個isa指針,該指針指向代碼段中該類所屬的類
當調用函數時,指針名先找到對象,當發現要調用函數時,就根據isa指針尋找該對象所屬的類

對象屬性的默認值

基本數據類型 0
C指針類型 null,可以作爲指針變量的值,不指向任何一個區域,NULL其實等價於0,就是一個宏
OC指針類型 nil 可以作爲指針變量的值,不指向任何一個區域,NULL其實等價於0,就是一個宏

nil == null 但是一般建議C指針用null,OC的類指針用nil

函數除了在函數的內部和和interface的大括弧中,其他地方都可以寫

類的實現可以放在使用類的後面

類方法聲明和實現時除了格式上

+ (return類型) functionName:[(數據類型) 形參名稱]

其他與普通方法無異

self相當於C/C++中的this指針,self指向該對象/類在代碼段中的地址

加載類

第一次訪問類時
第一次使用類時

類中繼承自NSObject的方法 - (NSString *) description{} 就相當於java中的toString方法

訪問權限問題

@private 只能在本類內部以及本類的方法實現中訪問
@public 只能在本類和本類的子類中訪問
@package 只能在當前的框架中訪問

點語法

OC中的點語法與Java、C#中的不同,OC中點語法默認調用程序員自己封裝好的setter和getter函數,那麼我們再setter、getter方法中就不能用點語法對類屬性進行賦值、防止無限遞歸

getter和setter方法的自動生成

@property 數據類型 屬性名

在interface中書寫左側語句則由編譯器自動生成對應屬性的getter和setter方法的聲明,但是此處屬性名爲真實屬性名去掉下劃線,否則自動生成的方法聲明是不符合規範的
@synthesize 屬性名
同樣的,在implementation中書寫上述代碼,則自動生成對應的getter和setter方法的實現

但是他們的實現都是默認自動生成一個私有的具有上述屬性名的屬性,如果需要生成對應的已經聲明的屬性的getter和setter方法,只需要書寫如下

@property 數據類型 屬性名 = _屬性名
@synthesize 屬性名 = _屬性名
@property(nonatomic/atomic,retain/assign,readwrite/readonly)
//nonatomic不會自動加線程安全鎖
//retain生成setter方法的時候先判斷新的是否等於舊的,如果不等於則先進行release再進行retain
//readwrite同時生成setter和getter
//readonly只生成getter
@property(nonatomic,retain,setter = xxx,getter = xxx)
//指定setter和getter方法的名字

測試指向對象的指針是否有某方法

responseToSelector:@selector(SEL)

判斷某指針指向的對象是否爲某類的對象或其子類的對象

isKindOfClass: [className class]
isMemberOfClass: [] 判斷是否爲對象
isSubclassOfClass: [] 是否爲子類對象

分組導航標記

pragma mark 分組名 就會在導航條對應位置顯示一個標題
pragma mark - [分組名] 就會在導航條對應的位置顯示一條水平分隔線

繼承

OC中只有單根繼承,沒有多繼承

類方法也能被子類繼承,被繼承的類方法可以用子類名繼承,也可以用父類名繼承

super只能用來調用父類方法,不能用來調用屬性

里氏替換原則(LSP):子類可以替換父類的位置,程序功能不受影響,但是指向子類對象的父類指針無法調用子類特有的方法和屬性

多態

指向重寫了父類方法的子類對象的父類指針,被調用時,執行的是子類重寫了的方法

id指針

id指針是一個萬能指針,可以指向任意OC對象
NSObject *也是一個萬能指針
但是使用id調用方法時,編譯器直接同構,使用NSObject指針時,編譯器會做編譯檢查
id指針只能調用對象的方法,不能使用點語法,如果使用點語法就會直接報錯。

內存中的五大區域

存儲局部變量

程序員手動申請的字節空間 malloc、calloc、realloc函數

BSS段

存儲未被初始化的全局變量、靜態變量

數據段

存儲已被初始化的全局、靜態變量、常量數據

代碼段

存儲代碼

retainCount

每個對象都有一個retainCount引用計數器
retain信號 即retainCount++
release信號 即retainCount–

內存泄漏

在方法中爲傳入的對象進行不適當的retain,就造成沒有適當的release

setter方法內:
- (void) setCar:(Car *car)
{
  if(_car != car)
  {
    [_car release];
    _car = car;
  }
}
//

野指針、殭屍對象

野指針:指針指向的對象已經被分配給別人
殭屍對象:對象已被釋放、但是這個對象佔有的空間還沒被分配給別人,殭屍對象無法被複活

殭屍對象檢查機制

Enable Zombie Objects 但是每當用到指針的時候,都會進行殭屍對象檢查,所以這非常消耗性能,那麼該如何避免殭屍對象錯誤呢,當一個指針成爲野指針以後,將這個指針的值設置爲nil

強指針

平常情況下聲明的一個指針就是強指針
在ARC的機制下,如果一個對象沒有任何一個強指針指向他,就會被立即釋放
也可以用_ strong、 _weak分別聲明強指針和弱指針

ARC機制下

某對象被釋放後、原來指向這個對象的弱指針自動被設置爲nil
@property中的retain參數不能用
####ARC機制下的使用建議
如果是OC對象類型,就用strong,不是OC對象類型就用assign
存在類間屬性互相引用的情況下,一端使用weak,一端使用strong

將整個程序從MRC轉換爲ARC: Edit—Convert

分類

    @interface 類名 (分類名) : 父類
    @end
@implementation 類名 (分類名)
@end

但是在分類中只能增加方法,不能增加屬性
如果分類中有和本類同名的方法,則優先調用分類中的方法,哪怕沒有調用分類的同文件
如果多個分類有同名的方法,則調用最後編譯的那個分類中的方法
###分類高級(非正式協議)
既然優先調用分類的方法、那我們就可以在某些層面上“篡改”apple公司已經編好的、令人不爽的方法,只需要爲該類建立一個分類,並在分類中“篡改”或添加自己想要該類擁有的方法即可

延展

延展是一個特殊的分類,只有聲明、沒有實現,和本類共享一個實現
延展可以新增任意的成員屬性,也可以寫@property,既生成私有屬性,也生成setter、getter方法的聲明和實現
用延展來爲類寫真私有屬性
也可以將私有方法的聲明寫在延展中,實現寫在本類的實現當中,提高代碼的可讀性
延展天生就是用來私有化成員的

block

與C中的函數類似
##block高級
將block作爲參數傳入
將block做返回值返回

協議(protocol)

協議專門用來聲明一大堆方法,只要某類遵循某個協議,那麼這個類就擁有該協議的所有方法
某類遵循某協議的語法:
@interface className : 父類名

@required和@optional

@required表示如果遵守該協議的類沒有實現,編譯器就會報警告
@optional表示如果未遵守該協議的類沒有實現,編譯器不會報警告
但是沒有關係,”反正只是警告而已”

協議之間可以繼承、並且可以多繼承

繼承語法

@protocol protocolName <父協議名>
@end

類的名稱可以和協議的名稱一致

異常處理

@try
{
  可能出現異常的代碼段
}
@catch(NSException *exc)
{
  對異常的處理
}
@finally
{
  此處無論是否發生異常都會被執行到
}

自動釋放池@autoreleasepool

最高法則:唯一的作用就是省略創建對象匹配的那個release

如果A類是B類的參數,那麼稱B類依賴於A類

多線程

NSThread

Swift

常量&變量

let定義常量,var定義變量

自動推導

會根據設置數值的右側代碼,推斷變量/常量的類型

永遠不會對變量/常量做隱式轉換,所以兩個不同類型的變量計算的時候,必須全權由程序員來做類型管理(強制轉換)

可選項

一個變量可以是本身的類型,也可以是nil
var y: Int ?= 10
可選項不能直接參與計算,但是可以“強行解包”
print( y! + 20)
就是添加驚歎號,表示:程序員承諾y一定是有值的,如果沒有,就在運行時候崩潰給我看

控制流

條件

if 條件 {
  expression;
}

if後沒有圓括號,但是語句必須有花括弧
switch可以判斷任意類型的數值,而且不需要break,各個case之間不會穿透,如果相對多個case執行同一個決定,只需要在case後面的值加逗號即可,不需要使用花括弧分隔作用域

字符串

substringWithRange(Range類型)
[int]..<[int] 用來定義一個範圍

數組


array.append()

array.removeFirst()
array.removeLast()
array.removeAll()

array[i] = sth

約定俗成

單參數的函數名稱最好寫成xxxWith
一個類寫在一個模塊中,一個模塊至少包含兩個文件.h寫類的聲明 .m寫類的實現
如果創建了一個類,就要爲該類寫一個與類同名的類方法,方法實現創建一個最純潔的類並返回
屬性名要求以下劃線開頭,局部變量不要求。故一般不會產生局部變量與類屬性重名的情況
所有協議都必須直接或間接地從NSObject基協議繼承

小技巧

  • 隱藏頂部狀態欄
- (BOOL)prefersStatusBarHidden
{
    return true;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章