0

我最近向应用程序添加了线程,这样网络请求就不会阻塞 UI。这样做时,我发现我不能再像实现线程之前那样设置我的实例变量。我的实例变量是一个声明如下的属性:

@property (nonatomic, strong) NSMutableArray *currentTopPlaces;

以下是我错误设置实例变量 self.currentTopPlaces 的方法:

dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
    __block NSArray *topPlaces = [FlickrFetcher topPlaces];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.tableRowCount = [topPlaces count];
        [[self currentTopPlaces] setArray:topPlaces];
    });

在我开始使用 GCD 之前,使用 [self currentTopPlace] setArray:topPlaces] 在阻塞版本中运行良好。

现在,我必须像这样设置它才能正常工作:

dispatch_queue_t downloadQueue = dispatch_queue_create("Flickr Top Places Downloader", NULL);
dispatch_async(downloadQueue, ^{
    __block NSArray *topPlaces = [FlickrFetcher topPlaces];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.tableRowCount = [topPlaces count];
        self.currentTopPlaces = topPlaces;
    });

有人可以向我解释使用之间的区别:

[[self currentTopPlaces] setArray:topPlaces];

和:

self.currentTopPlaces = topPlaces;

具体来说,为什么“setArray”调用在线程块中不起作用?

我认为 Objective-C 中的点符号是语法糖而不是强制性的。我想知道实现相同行为的“非糖”方式。

4

2 回答 2

5

[self currentTopPlaces]并且self.currentTopPlaces实际上是相同的,但是

[self.currentTopPlaces setArray:topPlaces]; // (1)
self.currentTopPlaces = topPlaces; // (2)

不是。(1) 将 的所有元素替换为 的self.currentTopPlaces元素topPlaces。(2) 分配一个新值self.currentTopPlaces(如果它不是nil则释放旧值)。

如果 self.currentTopPlacesis nil会发生差异:(1)什么都不做,因为该setArray:方法被发送到nil。(2) 为 赋一个新值self.currentTopPlaces

Btw: The __block modifier is not necessary in your code, because the block will not change the value of topPlaces.

于 2012-08-07T21:10:17.723 回答
2
[[self currentTopPlaces] setArray:topPlaces];
self.currentTopPlaces = topPlaces;

这是两种完全不同的表达方式。第一个是书面的,第二个是:

[self setCurrentTopPlaces:topPlaces];

如果你想用点表示法做第一个,那就是:

self.currentTopPlaces.array = topPlaces;
于 2012-08-07T21:01:32.480 回答