ObjC允许在@implementation中定义实例变量?ObjC的autoreleasepool是GC机制吗?为什么ObjC的init方法里面可以直接使用self?

目录

ObjC允许在@implementation中定义实例变量?

ObjC为什么用@前缀?

ObjC字符串为什么有@前缀?

ObjC的@autoreleasepool是什么?

ObjC的autoreleasepool是GC机制吗?

ObjC的@interface和@class

Swift和ObjC中IBOutlet和IBAction代表什么?

Swift和ObjC互调用

为什么ObjC的init方法里面可以直接使用self?


ObjC允许在@implementation中定义实例变量?

是的,ObjC允许接口@interface和@implementation中同时有实例变量定义,但需要保证一样。ARC引入后,ObjC允许实例变量只在@implementation中定义,@interface中可以不用。

ObjC为什么用@前缀?

ObjC设计之初是为了在C语言的基础上,扩展一些面向对象功能。它不期望改变C语言的本质,所以用@符号来增加ObjC的功能。

ObjC字符串为什么有@前缀?

这是为了和普通C语言字符串区分开, @前缀代表字符串是NSString *类型,这种类型并不能和char *直接等价。

ObjC的@autoreleasepool是什么?

本质上,它就是创建了一个自动释放池的局部block, 在此内部申请的任何对象都会自动加入,block结束后自动释放对应的对象。

  { 
    __AtAutoreleasePool __autoreleasepool;
    return 0;
  }
  自动释放池支持嵌套。

ObjC的autoreleasepool是GC机制吗?

不是,不管是ObjC 1.0 NSAutoreleasePool还是2.0的@autoreleasepool, 它们都是手动内存管理(MRC)的一种机制,只不过它与retain/release显得稍微智能化,它不属于GC机制,也不算所谓的"自动垃圾回收机制"。autoreleasepool是自动释放池,是程序员为了方便代码中一些自动创建的对象能得到及时清理的机制。为什么有这个需求?因为ObjC的对象创建有两种模式,一种是显式以alloc/copy/mutableCopy/new前缀的创建,这种对象约定是让程序员手动release,另外一种是不是以前面这种前缀的创建方法,这些对象创建之后会返回给调用者继续使用,使用完后如何释放就成为问题。autorelease pool就为了解决这些对象的自动释放问题,在自动释放池调用drain方法时向所有对象发送release,引用计数为0的对象会被清理。你会看到iOS或macOS程序一开始会创建自动释放池,目的也就是为了能自动清理一些对象。以UI线程事件循环和自动释放池为例,每次事件结束,都有一些和本次事件才有关联的对象需要自动清理,不需要留到下次事件循环,自动释放池也很自然有用。

ObjC的@interface和@class

@interface等同于大部分面向对象class关键字,@class在ObjC中仅仅用于前向声明类,这个区别需要格外注意。

Swift和ObjC中IBOutlet和IBAction代表什么?

IBOutlet 和 IBAction 是用于与 Interface Builder 交互的关键术语,IB代表Interface Builder
. Interface Builder 是 Xcode 中的一个图形界面设计工具,用于创建和管理 iOS 和 macOS 应用程序的用户界面。IBOutlet指示它与UI控件关联,IBAction指示它是UI控件事件响应。从定义上,它们肯定都是空,仅仅是指示作用。

Swift和ObjC互调用

苹果平台现有的很多框架、库都是ObjC编写,Swift的引入并不是将以前的库全扔掉,而是可以复用它们。可以在ObjC类开始加上@objc指示,Swift可以调用它。同样Swift代码中加上@objc前缀,表明ObjC可以调用它。

为什么ObjC的init方法里面可以直接使用self?

self是ObjC类成员方法的隐藏的第一个参数名,它和C++的隐式this指针是类似作用。可以查看.m文件对应的C代码找到端倪: clang -rewrite-objc demo.m (此处简化以省略必要的ObjC编译选项)

- (id) initWithAge:(int)age {  

    return [self init:age];  

}

对应的C代码如下:

static id _I_Student_initWithAge_(Student * self, SEL _cmd, int age) {

    return ((id (*)(id, SEL, int))(void *)objc_msgSend)((id)self, sel_registerName("init:"), (int)age);

}


若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!

微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值