1. 程式人生 > >IOS objective-c程式設計簡單入門

IOS objective-c程式設計簡單入門

文章目錄

準備工作

  1. 購買蘋果電腦.
    或者, 使用虛擬機器(vmware)安裝黑蘋果, 作業系統至少10.13.4. 反正是越新越好, 否則, 安裝不了新版的xcode. 這個方式比較艱難, 會出現各種奇怪的錯誤, 要到百度上搜索解決方法.
  2. 申請蘋果賬號(Apple ID)
  3. 安裝xcode, 版本至少9.4. 也是越新越好.

建立xcode專案

雖然有swift新語言, 但很多開源庫仍然是objective-c, 而且objective-c更容易和c/c++混合程式設計.
先建立一個xcode工程, 這個太簡單了. (以下圖片是通過快捷鍵command+shift+3截圖的)
xcode -> Fle -> New -> Project
選擇macOS -> Command Line Tool型別

基本語法

objective-c是C語言的超集, 支援C語言, 同時也是面象物件的語言. 學過C語言, 然後又學過C++或Java的程式設計師上手應該很快.
知識點: 類的宣告和實現

, 成員變數, 成員方法, 靜態方法, 構造方法, 銷燬方法

#import <Foundation/Foundation.h>

//宣告
@interface MyObject : NSObject
{
    //預設為protected, 其它的物件無法訪問
    int member;
}
// +表示靜態函式, -表示成員函式。
// c++/java程式設計師對這兩種型別的函式應該很熟悉了

//p1為第1個引數, p2為第二個引數; param2相當於p2的暱稱,
//呼叫這個函式時,也必須這樣寫。 比如 [MyObject staticFun: 1 param2:2];
//引數之間是用空白符分開的, c/c++/java都是用逗號分開的
+(int) staticFun: (int) p1 param2: (int) p2;

//init是預設建構函式.  instancetype可以理解為當前物件的型別
// 返回instancetype型別的函式,都可以理解為建構函式, 也可以新增帶引數的建構函式.
//如果不需要初始化,也可以省略掉預設構造方法
//objective-c建立建立物件時,會預設將記憶體清0
-(instancetype) init;

//銷燬物件時,會呼叫這個方法。
//如果沒有需要手動釋放的資源,可以省略掉這個函式
-(void) dealloc;

-(int) member;

-(void) setMember: (int) value;


@end

//實現
@implementation MyObject
+(int) staticFun: (int) p1 param2: (int) p2
{
    return p1 + p2;
}

//init是預設建構函式,返回instancetype型別的函式,都可以理解為建構函式
//如果不需要初始化,也可以省略掉預設構造方法
-(instancetype) init
{
    NSLog(@"default constructor");
    return self;
}

//普通成員函式
-(int) member
{
    return self->member;
}

- (void) setMember: (int) value
{
    self->member = value;
}

-(void) dealloc
{
    [super dealloc];
    NSLog(@"default deconstructor");
}
@end

類的使用方法如下:

            //呼叫靜態方法
            int ret =[MyObject staticFun:1 param2:2];
            NSLog(@"staticFun: %d", ret);
            
            //構造物件
            MyObject* obj = [[MyObject alloc] init];
            
            //呼叫方法
            [obj setMember:123];
            ret = [obj member];
            NSLog(@"get member: %d", ret);
            
            //釋放物件, 如果開啟了“自動引用數”,系統會釋放掉這個物件,不需要手動呼叫
            //[obj release];

分類和擴充套件

objective-c可以通過繼承來建立一個新的類, 也可以通過分類和擴充套件這兩種方式來為原有的類新增新功能

分類Categories

可以為已有的類新增新的方法, 但是不能新增成員變數

@interface NSString (Test)
-(NSString*) myFunc;
@end

@implementation NSString (Test)
-(NSString*) myFunc
{
    return @"test categorys";
}
@end

//測試
 NSString* str = @"my";
 NSLog(@"%@", [str myFunc]);

擴充套件Extensions

objective-c還支援別外一種方式來擴充套件介面, 如下:
在.h中宣告一些可以暴露的程式碼

@interface MyExtension : NSObject
{
    int m;
}
@end

在.m中宣告內部的一些成員

@interface MyExtension()
-(void) myPrivteFunc;
@end

@implementation MyExtension
-(void) myPrivteFunc
{
    NSLog(@"my private func");
}
@end;

在xcode的程式碼自動補全列表, 不會顯示myPrivteFunc方法, 從而達到隱藏程式碼的效果. (其實, 也可以強行呼叫.)

@property

上例中, 有一個成員變數member, 為了能夠設定和讀取它的值, 又添加了兩個相關的成員方法. objective-c提供了@property關鍵字, 來讓編譯器自動處理這個問題. 相當於一個高階的語法糖.

@interface MyProperty : NSObject
//編譯會自動生成一個成員變數_myProperty, 
// 再生成myProperty方法, 用於讀取_myProperty的值
// 還生成setMyProperty方法, 用於設定_myProperty的值.
@property int myProperty;
@end
@implementation MyProperty
@end

等價於以下這種形式

@interface MyProperty2 : NSObject
{
    int _myProperty;
}
-(int) myProperty;
-(void) setMyProperty:(int)myProperty;
@end

@implementation MyProperty2
-(int) myProperty
{
    return self->_myProperty;
}
-(void) setMyProperty:(int)myProperty
{
    self->_myProperty = myProperty;
}

使用方式

int ret;
MyProperty* obj = [MyProperty new];
[obj setMyProperty:123];
ret = [obj myProperty];
NSLog(@"get member: %d", ret);

為了使用@property的功能更強大, ojbective-c又給它添加了很多屬性.
比如

只允許讀取, 不允許修改
@property (readonly) int myProperty;

@property的屬性主要有
可寫屬性:
readwrite 預設屬性
readonly 只讀

賦值屬性:
assign
預設屬性, 使用簡單的賦值方式, 即x=y這種
retain
新值會呼叫retain函式, 舊值會呼叫release函式. 對C++程式設計比較熟悉的程式設計師, 應該容易理解這種場景.
copy
新值會呼叫copy函式來生成一個新的物件, 舊值會呼叫release.

原子屬性
nonatomic
預設情況下, getter和setter是原子訪問的(也就是執行緒安全), 這會影響效能, 因此開發者可以指定為非原子操作nonatomic

垃圾回收處理

objective-c也支援垃圾自動回收, (雖說沒有java這麼傻瓜化, 但是效能上肯定比java好, 可以理解為半自動回收吧)
如果工程開啟了自動引用計數(ARC), 那麼就不需要手動呼叫release函式. 但是各種賦值操作就得注意了, 一不小心釋放掉了一個正在使用中的物件, 程式就崩潰了. 所以才有了上面的retain, copy這兩處屬性, 然後又出現了 __weak , __strong 修飾符.
__strong
預設屬性, 表示強引用, 即引用計數必須正確的進行加減, 例如

@property (retain) __strong NSString str;  

它會呼叫新值的retain函式(即計數+1), 避免新值被釋放. 同時會呼叫舊值的release函式(即計數-1), 避免舊值記憶體洩露.

__weak
弱引用, 不改變計數值. 比如, 如果新值的生命週期一定比當前物件要長, 那麼操作引用計數沒有任何意義.

Protocol

類似於java中的interface.

//宣告協議
@protocol MyProtocol
-(void) myProtocol;
@end

//實現協議
@interface MyProtocolImpl: NSObject<MyProtocol>
@end
@implementation MyProtocolImpl
-(void) myProtocol
{
    NSLog(@"invoke protocol");
}
@end

//使用協議
@interface TestProtocol : NSObject
-(void) testProtocol:(id<MyProtocol>) callback;
@end

@implementation TestProtocol
-(void) testProtocol:(id<MyProtocol>) callback
{
    [callback myProtocol];
}
@end

原始碼

https://github.com/wzjwhut/objective-c-demo