Swift相比Objective-C不止增长了不少特性,还有很多修改,对于实际编程中最容易出现的错误莫过于Swift将几乎全部Objective-C中对应的类型,都由引用类型都修改成值类型。编程
好比开发中最经常使用到的数据类型array:数组
NSMutableArray *array1 = [NSMutableArray arrayWithArray:@[@1, @2, @3]];
NSMutableArray *array2 = array1;
[array2 removeLastObject];
NSLog(@"%@", array1); // 1, 2
复制代码
var array1 = [1, 2, 3]
var array2 = array1
array2.removeLast()
print(array1) // 1, 2, 3
复制代码
刚开始学习Swift时,只是以为这只是一个语言对于不一样数据类型的设计不一样而已,开发中只要注意对于须要函数内部修改的参数,加上inout便可。bash
可是随着对于Swift的深刻使用,愈来愈以为,这个设计相比于Objective-C的引用类型来讲,确实是更加的难以使用。ide
好比实现一个对于数组的排序封装类,将数组传入并将数组按照升序排序,这里采用最简单的冒泡排序实现,若是是Objective-C实现:函数
#import <Foundation/Foundation.h>
@interface MySort<ObjectType>: NSObject
- (void)sortWithArray:(NSMutableArray<ObjectType> *)array;
@end
@implementation MySort
- (void)sortWithArray:(NSMutableArray *)array {
if (!array || array.count < 2) {
return;
}
for (NSInteger end = array.count - 1; end > 0; end--) {
for (NSInteger begin = 1; begin <= end; begin ++) {
if ([array[begin] compare:array[begin - 1]] == NSOrderedAscending) {
id tmp = array[begin];
array[begin] = array[begin - 1];
array[begin - 1] = tmp;
}
}
}
}
@end
int main(int argc, char *argv[]) {
NSMutableArray *array = [NSMutableArray arrayWithArray:@[@9, @8, @7, @6, @5, @4, @3, @2, @1, @0]];
MySort *sort = [MySort new];
[sort sortWithArray:array];
NSLog(@"%@", array);
}
复制代码
由于Objective-C中,数组是引用类型,直接将数组传递就能够实现对其排序,若是将上述的代码用Swift实现,须要在函数中修改array,须要将参数加上inout来实现:学习
public class MySort<ObjectType: Comparable> {
public final func sortWithArray(array: inout [ObjectType]) {
guard array.count > 1 else {
return
}
for end in stride(from: array.count - 1, to: 0, by: -1) {
for begin in 1 ... end {
if array[begin] < array[begin - 1] {
let tmp = array[begin]
array[begin] = array[begin - 1]
array[begin - 1] = tmp
}
}
}
}
}
var array = [9,8,7,6,5,4,3,2,1,0]
var mySort = MySort<Int>()
mySort.sortWithArray(array: &array)
print(array)
复制代码
目前来看没有任何问题,下面假如须要排序类先将数据保存,并在其它方法中实现排序。ui
在Objective-C中,只须要为类添加一个成员,而且将方法传入的数组对象传递给它便可:spa
@interface MySort<ObjectType>: NSObject {
@private
NSMutableArray<ObjectType> *_array;
}
- (void)sortWithArray:(NSMutableArray<ObjectType> *)array;
@end
@implementation MySort
- (void)sortWithArray:(NSMutableArray *)array {
if (!array || array.count < 2) {
return;
}
_array = array;
}
- (void)sort {
for (NSInteger end = _array.count - 1; end > 0; end--) {
for (NSInteger begin = 1; begin <= end; begin ++) {
if ([_array[begin] compare:_array[begin - 1]] == NSOrderedAscending) {
id tmp = _array[begin];
_array[begin] = _array[begin - 1];
_array[begin - 1] = tmp;
}
}
}
}
@end
复制代码
可是Swift中就会出现问题:设计
public class MySort<ObjectType: Comparable> {
private var array: [ObjectType]?
public final func sortWithArray(array: inout [ObjectType]) {
guard array.count > 1 else {
return
}
self.array = array
sort()
}
private func sort() {
for end in stride(from: array!.count - 1, to: 0, by: -1) {
for begin in 1 ... end {
if array![begin] < array![begin - 1] {
let tmp = array![begin]
array![begin] = array![begin - 1]
array![begin - 1] = tmp
}
}
}
}
}
var array: [Int] = [9,8,7,6,5,4,3,2,1,0]
var mySort = MySort<Int>()
mySort.sortWithArray(array: &array)
// [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print(array)
复制代码
由于数组是值类型,将函数传入的数组传递给排序类的成员时:self.array = array 是一个默认拷贝的操做,在接下来的排序过程,只是对排序类中拷贝的数据进行排序。若是须要将函数传入的数组也修改排序,须要在sort()调用后,将本地拷贝的数组传递给外部的inout 参数:指针
public final func sortWithArray(array: inout [ObjectType]) {
guard array.count > 1 else {
return
}
self.array = array
sort()
array = self.array!
}
复制代码
这样作很是的很差,由于无缘无故的多出来两次数据的拷贝操做,最终我是使用了一个不太好的办法,就是利用指针来处理:
public class MySort<ObjectType: Comparable> {
private var array: UnsafeMutablePointer<[ObjectType]>?
public final func sortWithArray(array: inout [ObjectType]) {
guard array.count > 1 else {
return
}
self.array = withUnsafeMutablePointer(to: &array) { $0 }
sort()
}
private func sort() {
for end in stride(from: array!.pointee.count - 1, to: 0, by: -1) {
for begin in 1 ... end {
if array!.pointee[begin] < array!.pointee[begin - 1] {
let tmp = array!.pointee[begin]
array!.pointee[begin] = array!.pointee[begin - 1]
array!.pointee[begin - 1] = tmp
}
}
}
}
}
var array: [Int] = [9,8,7,6,5,4,3,2,1,0]
var mySort = MySort<Int>()
mySort.sortWithArray(array: &array)
print(array)
复制代码
这样子确实避免了拷贝,不过真的很是的很差看,也不方便,只是解决了问题而已。
有人有更好的办法解决欢迎分享。