Objective-C NSArray在传递给不同类的方法时无法更改

时间:2014-05-13 18:26:02

标签: ios objective-c c nsarray

我有一个NSArray,我需要更改其中的项目顺序。我写了一个确定新订单的方法:

+(NSArray*)sortProxyForms:(NSArray*)arrayOfForms
{
    NSArray* sortedForms = [arrayOfForms sortedArrayUsingComparator:^(HPSModelFormProxy* a, HPSModelFormProxy* b) {

        return [@(a.ordinal) compare:@(b.ordinal)]; // @(a.ordinal) aka Boxing turns int into NSNumber

    }];

    arrayOfForms = [sortedForms copy]; // DOES NOT WORK

    return sortedOfForms; // WORKS IF ASSIGNED IN THE CALLER

}

因此,我可以将NSArray传递给方法。我把这个方法称为:

[HPSModelUtilities sortProxyForms:_formProxies];

如果我真的尝试在方法中设置arrayOfForms(对_formProxies的引用),那么一旦我从方法返回,那么数组就不会改变。

但是,如果我从方法中返回已排序的数组并将其分配给调用方法中的NSArray,那么分配就可以了:

_formProxies = [HPSModelUtilities sortProxyForms:_formProxies]; // _formProxies NSArray is changed

_formProxies在调用类中声明,“HPSModelUtilities”是另一个类。

为什么NSArray可以在调用者中更改,但在被调用的方法中没有更改,即使它是通过引用传递的?

2 个答案:

答案 0 :(得分:3)

将值传递给方法时,会复制该值。这被称为“按值传递”。您传入的arrayOfForms是指针 NSArray 。这意味着传入时会复制指针。将此指针重定向到NSArray的另一个实例不会更改原始指针指向的位置。

我会将您的方法重命名为(NSArray*)sortedArrayFromProxyForms:(NSArray*)proxyForms

如果您确实想要更改NSArray引用指向方法的位置。这样做。

+ (void)sortProxyForms:(NSArray**)proxyForms {
    *proxyForms = sortedForms;
}

答案 1 :(得分:1)

您正在传递数组引用的副本(略微不同于通过引用传递),但是您将更改该引用指向此行的位置:

arrayOfForms = [sortedForms copy];

arrayOfForms不再指向您传递的数组实例,而是指向其他数组。您可以传递指针指针,并更改调用者指针指向的位置,但是对于您正在执行的操作,我认为重新分配是正常的。

如果您真的喜欢这里使用指针指针的功能:

+(void)sortProxyForms:(NSArray**)arrayOfForms {
    NSArray* sortedForms = [arrayOfForms sortedArrayUsingComparator:^(HPSModelFormProxy* a, HPSModelFormProxy* b) {

        return [@(a.ordinal) compare:@(b.ordinal)]; // @(a.ordinal) aka Boxing turns int into NSNumber

    }];

    *arrayOfForms = [sortedForms copy]; 
}

但我要补充说,这不是你在objective-c中经常看到的模式,所以当有其他替代方案时我会避免它。

另请注意,在调用此函数时,您需要添加&以获得额外的间接级别:

[HPSModelUtilities sortProxyForms:&_formProxies];