Как конвертировать NSMutableArray в NSArray в Objective-C?
NSArray *array = mutableArray;
Как конвертировать NSMutableArray в NSArray в Objective-C?
NSArray *array = mutableArray;
Ответы:
NSArray *array = [mutableArray copy];
Copyделает неизменные копии. Это очень полезно, потому что Apple может делать различные оптимизации. Например, отправка copyв неизменяемый массив только сохраняет объект и возвращает self.
Если вы не используете сборщик мусора или ARC, помните, что -copyсохраняет объект.
copyхорош , но как я могу узнать из документов, которые создают обычный NSArray, а не NSMutableArray?
NSArray& NSMutableArray, NSString& NSMutableString. Но не например, NSViewControllerкоторый всегда содержит изменяемое состояние.
An NSMutableArrayявляется подклассом, NSArrayтак что вам не всегда нужно конвертировать, но если вы хотите убедиться, что массив не может быть изменен, вы можете создать NSArrayлюбой из этих способов в зависимости от того, хотите ли вы, чтобы он был автоматически освобожден или нет:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
РЕДАКТИРОВАТЬ: Решение, предоставленное Георгом Schölly, является лучшим способом сделать это и намного чище, особенно теперь, когда у нас есть ARC и даже не нужно вызывать autorelease.
Мне нравятся оба основных решения:
NSArray *array = [NSArray arrayWithArray:mutableArray];
Или
NSArray *array = [mutableArray copy];
Основное различие я вижу в них , как они ведут себя , когда mutableArray равна нулю :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]его можно упростить до [nil copy]. В target-c любое сообщение, отправленное на ноль, всегда будет ноль. Важно помнить различие между «ничем» и «массивом, в котором ничего нет».
вы попробуйте этот код ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
а также
NSArray *myArray = [myMutableArray copy];
Ниже приведен способ преобразования NSMutableArray в NSArray:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
В Swift 3.0 появился новый тип данных Array . Объявите массив с помощью letключевого слова, тогда он станет NSArray. А если объявите с помощью varключевого слова, то он станет NSMutableArray .
Образец кода:
let newArray = oldArray as Array
В объективе-c:
NSArray *myArray = [myMutableArray copy];
В скором времени:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
Этот [mutableArray copy]антипаттерн есть во всем примере кода. Прекратите делать это для одноразовых изменяемых массивов, которые являются временными и освобождаются в конце текущей области.
Нет способа, которым среда выполнения могла бы оптимизировать бесполезное копирование изменяемого массива, который вот-вот выйдет из области видимости, уменьшится до 0 и будет освобожден навсегда.
NSMutableArrayк NSArrayпеременной не тайному его (что вопрос в OP составляет около). Предоставление такого значения (например, в качестве возвращаемого значения или в качестве свойства) может привести к очень сложным проблемам отладки, если это значение было неожиданно изменено. Это относится как к внутренним, так и к внешним мутациям, поскольку изменяемое значение является общим.
NSMutableArrayпеременной. Поскольку объект никогда не переставал быть изменяемым массивом, вызов методов с мутацией для него завершится успешно и приведет к изменению общих данных. Если, с другой стороны, исходный изменяемый массив был скопирован, изменив его на неизменяемый массив, а затем назначен NSMutableArrayпеременной и вызвав методы мутации, эти вызовы завершатся ошибкой, doesNotRespondToSelectorпоскольку объект, получивший вызов метода мутации, находится в факт неизменен и не отвечает на эти методы.
Если вы создаете массив с помощью изменчивости, а затем хотите вернуть неизменяемую версию, вы можете просто вернуть изменяемый массив как «NSArray» через наследование.
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
Если вы «доверяете» вызывающей стороне для обработки (технически все еще изменяемого) возвращаемого объекта как неизменяемого NSArray, это более дешевый вариант, чем [mutableArray copy].
Чтобы определить, может ли он изменить полученный объект, получатель сообщения должен полагаться на формальный тип возвращаемого значения. Если он получает, например, объект массива, типизированный как неизменяемый, он не должен пытаться изменить его . Неприемлемой практикой программирования является определение того, является ли объект изменчивым, основываясь на его принадлежности к классу.
Вышеуказанная практика обсуждается более подробно здесь:
NSArray *array = [mutableArray copy];