简体   繁体   English

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

[英]Objective-C NSArray can't be changed when passed to method in different class

I have an NSArray and I need to change the order of the items within it. 我有一个NSArray ,我需要更改其中的项目顺序。 I have written a method that will determine the new order: 我已经编写了一种确定新订单的方法:

+(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

}

So, I can pass the NSArray to be sorted into the method. 因此,我可以将NSArray传递给该方法。 I call the method like this: 我这样调用方法:

[HPSModelUtilities sortProxyForms:_formProxies];

If I actually try setting arrayOfForms (a reference to _formProxies ) within the method then once I have returned from the method then the array is unchanged. 如果我实际上尝试在方法中设置arrayOfForms (对_formProxies的引用),那么一旦我从方法中返回,则数组将保持不变。

However, if I return the sorted array from the method and assign it to the NSArray in the calling method then the assignment works: 但是,如果我从该方法返回排序后的数组并将其分配给调用方法中的NSArray ,则该分配有效:

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

_formProxies is declared in the calling class, and "HPSModelUtilities" is a different class. _formProxies在调用类中声明,“ HPSModelUtilities”是另一个类。

How come the NSArray can be changed in the caller, but not changed in the called method, even though it is passed by reference? 即使通过引用传递NSArray ,在调用者中如何进行更改,而在调用的方法中却不能进行更改?

When you pass a value into a method it is copied. 当您将值传递给方法时,它会被复制。 This is called "pass by value". 这称为“按值传递”。 The arrayOfForms you are passing in is a pointer to an NSArray . 您传入的arrayOfForms是一个指向 NSArray指针 This means that the pointer is copied when passed in. Redirecting this pointer to another instance of an NSArray does not change where the original pointer is pointing. 这意味着传入时将复制该指针。将该指针重定向到另一个NSArray实例不会更改原始指针指向的位置。

I would rename your method to (NSArray*)sortedArrayFromProxyForms:(NSArray*)proxyForms 我会将您的方法重命名为(NSArray*)sortedArrayFromProxyForms:(NSArray*)proxyForms

If you really want to change where your NSArray reference is pointing in the method. 如果您确实要更改方法中NSArray引用指向的位置。 Do it like this. 像这样做。

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

You are passing a copy of the array reference (subtly different than passing by reference), but then you are changing where that reference points with this line: 您正在传递数组引用的副本(与通过引用传递稍有不同),但是随后您通过以下行更改了该引用指向的位置:

arrayOfForms = [sortedForms copy];

arrayOfForms no longer points to the array instance you passed, but to a different array. arrayOfForms不再指向您传递的数组实例,而是指向另一个数组。 You could pass a pointer of pointer, and change where the caller's pointer is pointing, but for what you are doing, I think the reassignment is fine. 您可以传递指针的指针,并更改调用者的指针指向的位置,但是对于您正在执行的操作,我认为重新分配是可以的。

If you'd really like here's what your function would look like with pointer of pointer: 如果您真的想要这是使用指针指针的函数的外观:

+(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]; 
}

but I'll add the caveat that this isn't a pattern you see often in objective-c, so I'd avoid it when there are other alternatives available. 但我要补充说明的是,这不是您在Objective-C中经常看到的模式,因此,当有其他替代方法可用时,我会避免使用它。

Also note when calling this function you need to add the & to get the extra level of indirection: 还要注意,在调用此函数时,您需要添加&以获得额外的间接级别:

[HPSModelUtilities sortProxyForms:&_formProxies];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM