【Objective-C】Objective-C汇总

很好的参考:https://www.runoob.com/w3cnote/objective-c-tutorial.html

Objective-C:C的超集

Objective-Objective-C是C语言的严格超集:任何C语言程序不经修改就可以直接通过Objective-C编译器
Objective-C被描述为盖在C语言上的薄薄一层

源代码的文件扩展名

  • .h: 头文件
  • .m: 源代码文件,更常用,可以包含 Objective-C 和 C 代码
  • .mm: 源代码文件,可以包含 Objective-C 、 C 和 C++ 代码

#import和#include

  • 你可以使用标准的 #include 编译选项
  • #import 选项和 #include 选项完全相同,并且#import 可以确保相同的文件只会被包含一次
  • Objective-C 的例子和文档都倾向于使用 #import

消息传递

Objective-C里,对象之间互相传递消息。

  • C++里类别与方法的关系严格清楚,一个方法必定属于一个类别,而且在编译时(compile time)就已经紧密绑定,不可能调用一个不存在类别里的方法。
  • Objective-C里,类别与消息的关系比较松散,调用方法视为对对象发送消息,所有方法都被视为对消息的回应。所有消息处理直到运行时(runtime)才会动态决定,并交由类别自行决定如何处理收到的消息。

类的声明

在这里插入图片描述

方法声明

在这里插入图片描述

参考:https://www.yiibai.com/objective_c/objective_c_functions.html

Objective-C编程语言中方法定义的一般形式如下

- (return_type) method_name:( argumentType1 )argumentName1 
    joiningArgument2:( argumentType2 )argumentName2 ... 
    joiningArgumentn:( argumentTypen )argumentNamen {
    body of the function
}

示例:

/* 返回两个参数的最大值 */
- (int) max:(int) num1 secondNumber:(int) num2 {

   /* 局部变量声明 */
   int result;

   if (num1 > num2) {
      result = num1;
   } else {
      result = num2;
   }

   return result; 
}

方法调用

(1) 方括号语法(Bracket Syntax)

[object methodName];
[object methodNameWithArgument1:argument1 argument2:argument2];

[object methodName] 调用object对象的method方法
在 Objective-C语言里,方法和实现的关系不是在编译时决定的,而是在运行时决定的。

举例:

- (void) setColorToRed: (float)red Green: (float)green Blue:(float)blue; /* 声明方法*/

[myColor setColorToRed:1.0 Green:0.8 Blue:0.2]; /* 调用方法*/

(2) objc_msgSend 消息发送机制

是一种动态决议的间接调用方式

// 调用无参数方法
objc_msgSend(obj, "methodName");

// 调用有参数方法
objc_msgSend(obj, "methodNameWithArgument1:argument2:", argument1, argument2);

比如

objc_msgSend(v6, "addScriptMessageHandler:name:", self, CFSTR("windmill"));

含义是调用v6这个对象的addScriptMessageHandler:name:方法,方法的参数1是self,参数2是CFSTR("windmill")

根据addScriptMessageHandler:name:方法的定义:

(void)addScriptMessageHandler:(id<WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

addScriptMessageHandler:name: 是 WKUserContentController 类的一个实例方法

  • 参数1的类型是id<WKScriptMessageHandler>,参数名是scriptMessageHandler,形参名称省略(第一个参数可以没有形参名称,后面的参数必须有形参名称;当然也可以理解为第一个参数的形参名称体现在了"methodNameWithArgument1"这个方法名里)
  • 参数2的类型是NSString *,参数名是name,形参名称是name

协议

协议是一组没有实现的方法列表,类似Java中的"接口"
任何类都可以声明自身实现了某个协议

非正式协议与正式协议

  • 非正式协议已经被废弃不再使用
  • 正式协议中,一个类必须 实现它声明匹配的协议中的所有方法,否则编译器会报错

协议的语法

@protocol起始,@end结束,中间为方法列表

@protocol Locking
- (void)lock;
- (void)unlock;
@end

Delegate 委托机制

alloc 方法

OC中经常使用 NSObject *object = [[NSObject alloc] init]; 这行代码去创建一个对象

通过对alloc底层源码的分析, 可以了解到:
① alloc的主要目的是开辟内存空间;
② 主要的核心逻辑是 计算内存大小->申请内存空间->绑定isa;
③ 计算内存大小是按照16字节对齐的。

参考:https://www.cnblogs.com/mysweetAngleBaby/p/16747295.html

IDA反编译看到的代码

bool __cdecl -[SpotifyAppDelegate application:openURL:options:](
        _TtC24MusicApp_ContainerWiring18SpotifyAppDelegate *self,
        SEL a2,
        id a3,
        id a4,
        id a5)
{
	……
}
  • bool是返回值类型
  • __cdecl 是一种函数调用约定(calling convention),指定由调用者负责清理堆栈
  • - 表示是对象方法
  • SpotifyAppDelegate是一个类,是该方法所属的类
  • application:openURL:options:是方法签名
    • application是方法名称
    • openURL是参数2的形参名称
    • options是参数3的形参名称
  • ( _TtC24MusicApp_ContainerWiring18SpotifyAppDelegate *self, SEL a2, id a3, id a4, id a5)是方法的参数。每个参数都有一个类型和一个名称,用于在方法的实现中引用和操作这些参数。
    • _TtC24MusicApp_ContainerWiring18SpotifyAppDelegate *self: 一个指向SpotifyAppDelegate对象的指针,表示方法的调用者。
    • SEL a2: 一个选择器(Selector),表示方法的方法名。
    • id a3, id a4, id a5: 这些是真正的参数,id类型,可以表示任意类型的对象。

该方法对应的方法签名是- (bool)application: (UIApplication *)application openURL: (NSURL *)url options: (NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
所以:

  • id a3 对应的是参数1 application
  • id a4对应的是参数2 url
  • id a5对应的是参数3 options

OC中的block

https://juejin.cn/post/6844903525290360840

(1) 没有返回值、没有参数的block

void (^voidBlock)() = ^{};
voidBlock();

(2) 没有返回值、有一个参数的block

void (^parameterBlock)(NSInteger parameter) = ^(NSInteger parameter){
    NSLog(@"=====parameterBlock");
};
parameterBlock(1);

(3)没有返回值、有两个参数的block

void (^parametersBlock)(int par1, int par2) = ^(int par1, int par2){
    NSLog(@"=====parameterBlock");
};
parametersBlock(2,3);

等等

常见方法

stringFromObject:

作用是将一个对象转换为字符串形式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值