Ios 块中使用的NSMutableArray实例

Ios 块中使用的NSMutableArray实例,ios,objective-c,block,Ios,Objective C,Block,下面的代码段使用GCD计算一组整数并将它们存储在数组中 factArray={1!、2!、…n!}其中k!指定阶乘(k)=k*(k-1)*…*2*1 我想知道为什么我可以将对象添加到块内的factArray变量(NSMutableArray的实例),尽管factArray不是用_块限定符声明的 NSUInteger n = 10; NSMutableArray *factArray = [[NSMutableArray alloc] initWithCapacity:n]; __block NS

下面的代码段使用GCD计算一组整数并将它们存储在数组中

factArray={1!、2!、…n!}其中k!指定阶乘(k)=k*(k-1)*…*2*1

我想知道为什么我可以将对象添加到块内的factArray变量(NSMutableArray的实例),尽管factArray不是用_块限定符声明的

NSUInteger n = 10;
NSMutableArray *factArray = [[NSMutableArray alloc] initWithCapacity:n];
__block NSUInteger temp = 1;
dispatch_apply(n,
               dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
               ^(size_t s) {
                   NSUInteger w;
                   temp *= floor(s) + 1;
                   w = temp;
                   [factArray addObject:@(w)];
               });

__block NSArray *sortedArray;
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    sortedArray = [factArray sortedArrayUsingComparator:^NSComparisonResult(NSNumber *n1, NSNumber *n2) {
        return [n1 compare:n2];
    }];
    NSLog(@"%@", sortedArray);
});

当然,如果我们添加u块限定符,此代码仍然有效。

factArray
是一个变量,如
temp
。这是一个指针;它保存其他东西的内存地址。块获取该指针的副本,就像它获取
temp
的副本一样。但是,指向的对象不会被复制。它保持在原来的位置,并且仍然是一个
NSMutableArray
。您可以通过指针向它发送消息;这不会改变指针的值。它仍然指向相同的位置,并且可以在不更改指针的情况下修改对象的内容

NSUInteger n = 10;
NSMutableArray *factArray = [[NSMutableArray alloc] initWithCapacity:n];
__block NSUInteger temp = 1;
dispatch_apply(n,
               dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
               ^(size_t s) {
                   NSUInteger w;
                   temp *= floor(s) + 1;
                   w = temp;
                   [factArray addObject:@(w)];
               });

__block NSArray *sortedArray;
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    sortedArray = [factArray sortedArrayUsingComparator:^NSComparisonResult(NSNumber *n1, NSNumber *n2) {
        return [n1 compare:n2];
    }];
    NSLog(@"%@", sortedArray);
});
如果您想摆脱现有的数组并创建一个新的数组,并调用该数组
factArray

dispatch_apply(n, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
               ^(size_t s) {
                   factArray = [NSMutableArray array];
});
然后更改指针的值,然后需要
\u块
说明符


通俗地说,由于ObjC对象只能通过指针访问,因此我们通常将指针当作对象来引用。区别在很大程度上并不重要;这是其中一种情况。

您混淆了变量和对象。变量指向对象,但变量与它指向的对象不同。
\u块
存储说明符影响变量存储,但实际上对变量指向的对象没有任何影响。除此之外,该对象还可以由任意数量的变量指向,它不在乎它们的存储是什么样子——它们指向它时,它只是在堆中浮动


因此,简而言之,你不是在改变变量,而是在改变对象。

好吧。。。您不需要修改factArray,所以。。。(是的,这正是闭包被称为闭包的原因。)太棒了。清晰而令人敬畏的答案。谢谢你抽出时间。