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

猜你喜欢

转载自blog.csdn.net/wzj_whut/article/details/85225196