OC语言基础

简介: OC语言基础

版本

Objective-C有两个版本1.0和2.0,macos 10.5(2005年)及以后的系统都是2.0,所有iOS系统使用的都是2.0,提供了__OBJC2__可以判断版本。

格式

@符号 OC新增的关键词大部分是以此符号开头

头文件 使用#import ""

文件后缀 h-头文件,m-实现文件,mm-包含OC和C++的文件。

#import

int main(int argc, char *argv[]){

@autoreleasepool{

NSLog(@"Hello World!");

}

return 0;

}

数据类型和API

NS前缀

一般是指来自NextStep的系统API。

NSString

NSString* strA = @"aaa";

NSLog(@"strA=%@", strA); //打印格式

NSInteger/NSUInteger

#if __LP64__ || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64

typedef long NSInteger;

typedef unsigned long NSUInteger;

#else

typedef int NSInteger;

typedef unsigned int NSUInteger;

#endif

Apple的UIKit代码一般都用的是NSInteger,NSInteger在32系统是int,64位系统是long,兼容性更好。

要注意把NSInteger转换成int时可能会溢出。

NS_ENUM

NS_ENUM是一个OC中的宏,可以指定底层数据类型,是对enum的一种封装,在OC中,几乎不使用enum

typedef NS_ENUM(NSInteger, FlyState) {

   FlyStateOne,

   FlyStateTwo,

   FlyStateThree

};


FlyState state = FlyStateOne;

NS_OPTIONS

在NS_ENUM的基础上,使得按位或计算的结果能够返回正确的数据类型。

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {

   UIViewAutoresizingNone                 = 0,

   UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,

   UIViewAutoresizingFlexibleWidth        = 1 << 1,

   UIViewAutoresizingFlexibleRightMargin  = 1 << 2,

   UIViewAutoresizingFlexibleTopMargin    = 1 << 3,

   UIViewAutoresizingFlexibleHeight       = 1 << 4,

   UIViewAutoresizingFlexibleBottomMargin = 1 << 5

};

NSLog

NSLog(@"Hello World");

2021-10-09 16:49:58.733819+0800 RTCSolution[250:4239] [MC] Reading from public effective user settings.

时间 + 程序名 + [进程号:线程号] + 输出信息。

autoreleasepool

用途待补充。

NSObject

基础类。NSObject既是protocol,又是interface,定义见 NSObject.h

@protocol NSObject

//...

@end

@interface NSObject

//...

@end

id

注意id是一种类型,相当于指向NSObject的指针,因而能用于指向所有类类型的变量。

instancetype

instancetype的作用,就是使那些非关联返回类型的方法返回所在类的类型,好处是能够确定对象的类型,能够帮助编译器更好的为我们定位代码书写问题。

布尔类型

C语言标准中没有定义布尔类型,但提供了一个头文件定义布尔类型,方便使用

#include


bool flag = true;

bool flag = false;

C++标准默认包含了boo类型,用法同上。

objective-c中定义了多种布尔类型,一般建议使用BOOL

Name

Typedef

Header

True Value

False Value

BOOL

signed char

objc.h

YES

NO

bool

_Bool (int)

stdbool.h

true

false

Boolean

unsigned char

MacTypes.h

TRUE

FALSE

NSNumber

__NSCFBoolean

Foundation.h

@(YES)

@(NO)


语法规则

interface

类的定义以关键词interface开始,以end结束

@interface MyClass : NSObject

- (void) sayHello;

- (void) sayHelloWithParaA:(NSString* _Nonnull)paraA

                   paraB:(NSString* _Nonnull) paraB;

@end

类成员

包含类成员的的定义

interface{}可以定义变量,权限默认为protected, implementation{}也可以定义变量,权限为private。

objective-2.0引入了property,方便getter/setter类变量的使用。

property属性

@property(copy) NSString* name;

@property(readonly) int age;

property的特性在2006年wwdc发布,把原来的实例变量定义成properties属性。
成员变量需要手动声明setter和getter,其他类也可以通过->访问。

从xcode4.5开始,property不需要再添加@synthesize来合成。

//最短写法

@property BOOL isOpen;

//最复杂的写法

@property (nonatomic, readonly, copy, getter=theNewTitle, setter=setTheNewTitle:, nullable) NSString *newTitle;

类实现implementation

implementation

@implementation MyClass

- (void)sayHello {

   NSLog(@"say hello");

}

- (void) sayHelloWithParaA:(NSString* _Nonnull)paraA paraB:(NSString* _Nonnull) paraB {

   NSLog(@"paraA=%@, paraB=%@", paraA, paraB);

}

@end

类方法&实例方法

类似Java中的Static Method,不需要实例化就能使用,标志是前面的 +

普通的对象方法前面是-

传递消息/对象方法调用

类/对象的方法调用,用OC的说法是传递消息

普通的函数调用同C,对于类或对象的方法,调用格式如下:

[mycls sayHello];

[mycls sayHelloWithParaA:strA paraB:strB];

protocol协议

类似java中的interface,特点:

协议中可以定义可选的方法,也就是非必须实现的方法,关键词是optional

@protocol Printable

-(void)print:(NSString*)str;

@optional

-(void)sayHello:(NSString*)str;

@required //不加optional默认即为required

   -(void)sayName:(NSString*)name;

@end


@interface MyClass : NSObject  //实现类可以实现多个protocol

@end

category分类

给一个已经存在的类增加方法,而不用去修改类本身的源码,即使开发者没有该类的源码也可以如此使用。

NSObject+Json+XML.h 定义

@interface NSObject (Json)

-(NSString)toJson;

@end

@interface NSObject (XML)

-(NSString)toXML;

@end

NSObject+Json+XML.m 实现

@implementation NSObject (Json)

-(NSString)toJson {

//...

}

@end

@implementation NSObject (XML)

-(NSString)toXML {

//...

}

@end

main.m 使用

#import "NSObject+Json+XML.h"

@implementation XYZController

-(void)test {

NSObject *obj = [[NSObject alloc]init];

NSString *json = [obj toJson];

NSString *xml = [obj toXML];

}

@end

Extension扩展

扩展不仅可以添加新的方法,还可以添加实例变量,都是private。

使用扩展时,类名后的小括号中不添加任何东西。

扩展中声明的方法必须在相应类的implementation代码中实现。

// 如下代码位于 MyClass.h 文件中

@interface MyClass : NSObject

- (float)value;

@end

 

// 如下代码位于 MyClass.m 文件中

@interface MyClass () {  // 扩展

   float value;

}

- (void)setValue:(float)newValue;

@end

 

// 实现

@implementation MyClass

- (float)value {

   return value;

}

- (void)setValue:(float)newValue {

   value = newValue;

}

@end

class关键词

在一些代码的开头文件有这样的用法

//ClassA.h

@class ClassB


//ClassB.h

@class ClassA

用于两个头文件相互引用的时候,避免死循环,编译报错。

其中一方,不要使用@#import引入对方的头文件,而使用class关键词。

block闭包

OC语言对闭包的实现。闭包允许一个函数访问声明该函数运行上下文中的变量。

//定义一个函数,入参是blcok

void logBlock(int (^theBlock)(int para)) {

   NSLog(@"Closure var X:%i", theBlock(1));

}


//main()

//定义block变量,变量名字为myBlock

int(^myBlock)(int);

int x = 42;

//block变量赋值

myBlock = ^(int i) {

   return i + x;

};

logBlock(myBlock); //输出Closure var X:43

参考上面的例子,定义了一个myBlock变量,入参是一个int型,返回值也是int型。

然后将一个声明的block赋值给myBlcok,在这个实现函数中访问了main()函数上下文定义的局部变量x=42

调用logBlock函数时,将myBlock作为入参传入,在logBlock函数内部虽然没有定义x变量,但是仍然可以访问x。这里在闭包函数内部默认做了一次复制操作,保证可以正常访问到x。

NULL/nil

标志

含义

NULL

(void *)0

一般赋给C指针变量

nil

(id)0

Objective-C 对象的字面空值

Nil

(Class)0

Objective-C 类的字面空值

NSNull

[NSNull null]

用来表示空值的 Objective-C 对象

这里Class不了解

箭头运算符和点运算符

箭头运算符(->)从C继承,用法同C,比如对象是一个指针,访问对象的变量就可以用obj->name。

点运算符(.)除了C中的用法,也用于getter和setter方法,等号左边就是setter方法,等号右边就是getter方法。

NSLog(@"name = %@", obj.name); //调用了getter方法

NSLog(@"name = %@", [obj name]);


obj.name = @"Jim"; //调用了setter方法

[obj setName:@"Jim"];

ARC

自动引用计数。(Automatic Reference Counting)在iOS 5引入,时间是2011 WWDC。

作用域修饰符private/public/protected

指令

意思

@private

作用范围只能在自身类

@protected

作用范围在自身类和继承自己的子类,什么都不写,默认是此属性。

@public

作用范围最大,在任何地方

@interface Boss : NSObject {

@public

   NSString* name;

@private

   int age;

@protected

   NSString *job;

}

@end

pragma mark

纯粹代码阅读方便,不影响编译

#pragma mark - 接口主类

#pragma mark -

OC面向对象特性

  • interface用于定义类
  • implementation用于类的实现
  • property用于定义属性
  • 也可以直接定义成员变量。
  • 成员函数。可以定义+型类成员函数,也可以定义-型对象成员函数。
  • protocol用于定义类似Java的interface,里面可以定义必须实现和可选实现的方法。
  • protocol可以继承其他的protocol,类可以实现多个protocol
  • category分类可以给一个类添加方法,这个类可以没有源码。category有自己的名字。
  • extension扩展不仅可以添加方法,也可以添加实例变量。新增加的方法必须在类中实现,用于声明私有属性,私有方法,私有成员变量。

问题记录

1 category和extension的适用场合。

可参考 https://www.jianshu.com/p/6e8a398b9c0b

2 m文件的implementation中可否定义没有在interface中声明的方法?比如RTCSampleChatViewController的initializeSDK。测试了一下可以,这样的方法可以被内部其他方法调用,但是没有声明在头文件中,不可被外部调用。

3 OC的对象构造和析构规则是什么alloc init创建的对象,怎么释放?

参考资料

NS_ENUM

https://www.jianshu.com/p/994dc9f4958d

目录
相关文章
|
算法 C语言
C语言算法基础-在一个单链表中值为y的结点前面插入一个值为x的结点
题目:3.4设计一个算法,在一个单链表中值为y的结点前面插入一个值为x的结点。即使值为x的新结点成为值为y的结点的前驱结点。 题目来自李云清版《数据结构》
288 5
C语言算法基础-在一个单链表中值为y的结点前面插入一个值为x的结点
|
C语言
【C语言学习者必会的题目集锦1】巩固基础,稳步提高
【C语言学习者必会的题目集锦1】巩固基础,稳步提高
98 0
【C语言学习者必会的题目集锦1】巩固基础,稳步提高
|
C语言
[C语言学习]C语言程序设计基础(三)
[C语言学习]C语言程序设计基础(三)
135 0
[C语言学习]C语言程序设计基础(三)
|
Linux C语言 iOS开发
[C语言学习]C语言程序设计基础(二)
[C语言学习]C语言程序设计基础(二)
161 0
[C语言学习]C语言程序设计基础(二)
|
存储 程序员 C语言
[C语言学习]C语言程序设计基础(一)
[C语言学习]C语言程序设计基础(一)
213 0
[C语言学习]C语言程序设计基础(一)
|
存储 自然语言处理 Linux
0基础C语言自学教程——收官之战——第十四节 文件的编译和链接
这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
149 0
0基础C语言自学教程——收官之战——第十四节 文件的编译和链接
|
存储 编译器 数据库
0基础C语言自学教程——第十三节 文件操作
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
138 0
0基础C语言自学教程——第十三节 文件操作
|
小程序 程序员 编译器
0基础C语言自学保姆教程——第十二节 动态内存分配
在开辟数组的过程中,其必须是一个定长的数组,就是在开辟空间的过程中就要指定大小;并且空间开辟的大小是固定的。
146 0
0基础C语言自学保姆教程——第十二节 动态内存分配