dev-blog icon indicating copy to clipboard operation
dev-blog copied to clipboard

GCD 深入理解:第一部分中单例中为什么要使用箭头“->”符号

Open HansZhang opened this issue 7 years ago • 4 comments

有一个疑问,在讲到单例部分的时候,下面段代码中对photosArrayconcurrentPhotoQueue都使用的->箭头引用来实例化,好奇为什么要这么用?如果用.点符号或者直接使用_下划线会有什么不一样的吗?希望能有人帮忙解答一下,谢谢。

+ (instancetype)sharedManager
{
    static PhotoManager *sharedPhotoManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedPhotoManager = [[PhotoManager alloc] init];
        // 这里以及下面👇的属性引用使用箭头符号的用意是什么?
        sharedPhotoManager->_photosArray = [NSMutableArray array];
 
        // ADD THIS:
        sharedPhotoManager->_concurrentPhotoQueue = dispatch_queue_create("com.selander.GooglyPuff.photoQueue",
                                                    DISPATCH_QUEUE_CONCURRENT); 
    });
 
    return sharedPhotoManager;
}

HansZhang avatar Mar 07 '17 06:03 HansZhang

很好的问题!在 PhotoManager 的定义中:

@interface PhotoManager ()
@property (nonatomic, strong) NSMutableArray *photosArray;
// ...
@end

有属性photosArray,但在初始化的时候,不应该直接访问属性,而要访问其背后的 ivar(实例变量),也就是_photosArray。这时候就不能用点语法了(点语法本质上是一种语法糖,根据上下文的不同,实际会向属性的 getter 或 setter 发消息),而->可以直接访问 ivar。

你可能需要再过一遍 Objective-C 的文档,了解 property 及编译器做了什么。

nixzhu avatar Mar 07 '17 09:03 nixzhu

首先感谢你的回复。 其实我开这个issue的问题很傻,因为我本意是想问为什么没有直接这样用

_photosArray = [NSMutableArray array];

我刚刚细想,这是TM是在类方法中啊,当然不能这么用😂,所以一开始这是个很粗心的问题🌚。

但是如果继续就您回复的要点来看,photosArray的初始化实际上是在sharedPhotoManagerinit方法执行完成之后进行的,而不是在init方法中,所以其实这里我觉得是可以正常使用点语法的。

HansZhang avatar Mar 07 '17 16:03 HansZhang

你说的对,这里也可以使用点语法直接访问属性,那么访问实例变量的目的可能是为了节省发消息的时间。如果不对,我就要找时间再看看Objective-C的语法😄。不瞒你说,我大概两年没用Objective-C写代码了。

nixzhu avatar Mar 07 '17 23:03 nixzhu

@nixzhu @HansZhang 学到了新知识。

alfredcc avatar Apr 12 '17 06:04 alfredcc