Objective-C

Hello-world

Objective-C是C语言的超集,完全兼容标准C语言并在其基础上添加了面向对象,消息机制以及反射等。 IDE 选择XcodevsCode等,先敲个简单的"hello world":

#import <Foundation/Foundation.h>

int main(int argc, char *argv[]){
    @autoreleasepool{
        NSLog(@"Hello World!");
    }
    return 0;
}

代码说明:

编译命令

# objc 编译时指定导入的framework
clang -framework Foundation hello.m -o hello.o

Objective-C的面向对象语法源自 SmallTalk,消息传递(Message Passing)风格。在代码风格方面,这是它与C Family语言(包括C/C++、Java、PHP)差别最大的地方。

类的定义与实现

在 oc 中,强制要求将类分为声明interface和实现implementation两个部分。声明放在 .h 文件,实现放在 .m 文件中。

在 oc 中大部分类都是直接或间接的继承 NSObject 。这个类遵循 NSObject 协议,提供了一些通用的方法(初始化、垃圾回收等),通过继承 NSObject,可以从其中继承访问运行时的接口,并让对象具备 objc 对象的基本能力。

interface

// @interface 定义类(Hello)
@interface ClassName: NSObject
// @property 定义属性
@property property_type *property_name;
@property property_type property_name;

+ (return_type) class_method; // 类方法
- (return_type) instance_method1; // 一般的实例方法
- (return_type) instance_method2: (int) p1; // 单个参数
- (return_type) instance_method3: (int) p1 andPar: (int) p2; // 多个参数
@end

implementation

// @implementation 实现类(ClassName)
@implementation ClassName : NSObject

+ (return_type)class_method {
	// TODO
}

- (return_type)instance_method1{
	// TODO
}

- (return_type)instance_method2: (int) p1 andPar: (int) p2{
	// TODO
}
@end

Interface, Implementation 定义的实体变量两者区别在于访问权限的不同;

Implementation 区段定义私有成员更符合面向对象之封装原则,因为如此类别之私有信息就不需曝露于公开 interface(.h文件)中。

protocol

// @protocol 声明协议(MyProtocol)
@protocol MyProtocol
// 默认为 @required 强制
- (void)bar;
@optional // 可选
- (void)foo;
@end

// 使用协议
@interface MyPro : NSObject <MyProtocol>
- (void)bar;
@end

创建对象

自定义初始化:

- (id) init {
    if ( self=[super init] ) {   // 必须调用父类的init
        // do something here ...
    }
    return self;
}

Block

block声明:returnType (^blockName)(argumentType1, argumentType2, ...);

block实现:

returnType (^blockName)(argumentType1, argumentType2, ...) = ^(argumentType1 param1, argumentType2 param2, ...){
    //do  something   here
};
// 定义一个 callbackLogger 块类型
typedef void (^callbackLogger)(void);
// 作为一个函数的参数
void genericLogger(callbackLogger blockParam) {
  blockParam();
  NSLog(@"%@", @"This is my function");
}

int main(int argc, char *argv[]) {
  @autoreleasepool {
    // exmaple 1:将一个值乘以2
    int (^multiply)(int) = ^(int a) {
      return a * 2;
    };
    NSLog(@"Multiply x2: %d", multiply(3));

    // exmaple 2:作为函数参数
    callbackLogger myLogger = ^{
      NSLog(@"%@", @"This is my block");
    };
    genericLogger(myLogger);
    // exmaple 2.1: inline 调用
    genericLogger(^{
      NSLog(@"%@", @"This is my second block");
    });
  }
  return 0;
}

常用类型

文件操作

// 初始化 NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
// fileExistsAtPath 判断路径是是否存在
if ([fileManager fileExistsAtPath:@"/tmp/zznQ.txt"] == YES) {
  NSLog(@"File exists");
} else {
  NSLog(@"File not exists");
}

// contentsEqualAtPath 比较两个文件的内容
if ([fileManager contentsEqualAtPath:@"/tmp/file1.txt"
                             andPath:@"/tmp/file2.txt"] == YES) {
  NSLog(@"File contents match");
}

// copyItemAtPath 复制一个文件
if ([fileManager copyItemAtPath:@"/tmp/file1.txt"
                         toPath:@"/tmp/file2.txt"
                          error:nil] == YES) {
  NSLog(@"Copy successful");
}
// 移动文件
// moveItemAtPath:toPath:error:
// 删除文件
// removeItemAtPath:error:

// 文件管理器接受 NSURL 类型参数的版本来定位资源。
// copyItemAtURL:toURL:error:
// removeItemAtURL:error:

// NSURL
// fileURLWithPath 创建NSURL对象
NSURL *fileSrc = [NSURL fileURLWithPath:@"/tmp/file1.txt"];
NSURL *fileDst = [NSURL fileURLWithPath:@"/tmp/file2.txt"];
[fileManager moveItemAtURL:fileSrc toURL:fileDst error:nil];

// 快捷的写入文件方式
NSString *tmp = @"something temporary";
[tmp writeToFile:@"/tmp/tmp1.txt"
      atomically:YES
        encoding:NSASCIIStringEncoding
           error:nil];
// NSURL版本:writeToURL:atomically:encoding:error:

// 通过 NSFileHandle 写入文件
NSFileHandle *fileHandle =
    [NSFileHandle fileHandleForWritingAtPath:@"/tmp/tmp2.txt"];
// 内容追加到文件末尾
[fileHandle seekToEndOfFile];
[fileHandle writeData:[tmp dataUsingEncoding:NSUTF8StringEncoding]];
[fileHandle closeFile];
}

Runtime

Break frida-objc-bridge

Swift