iOS Dev

swift中的Delegate

2016-06-17  本文已影响3548人  庸者的救赎

在iOS开发中,代理模式(protocol - delegate)是界面之间数据传递最为常见的一个设计模式

在Cocoa框架中也有大量使用,可以说是作为iOS开发者必备技能。

在我们OC开发时候使用delegate一般会把修饰符写成weak,这样在这个delegate实际的对象被释放的时候,会被置为nil,避免内存泄露。代码大致如下:

@property (nonatomic, weak) id<MGIndexAdReusableViewDelegate> delegate;

那么一般写过OC的童鞋去写swift,也会照本宣科,也设置为weak,没有错,但是事实情况会是怎样呢 ?看如下代码:

protocol TestDelegate {
  func testMethod()
}

class TestClass {
  weak var delegate: TestDelegate?
}

class ViewController: UIViewController, TestDelegate {
  var testInstance: TestClass!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    testInstance = TestClass()
    testInstance.delegate = self // error: 'weak' cannot be applied to non-class type 'TestDelegate'
  }
  
  func testMethod {
    print("Test!")
  }
}

上面注释部分是报错信息,为什么呢 ?

这是因为swift中的protocol是可以被除class类型以外的struct type和enum type所遵守的,那么原因不言而喻了。struct type和enum type,他们本身是不通过引用计数来管理内存的,所以也就不能使用weak来修饰,那么怎么办呢 ?

方法有两种

1.将protocol声明为Objective - C的,通过在protocol前面加@objc关键字来实现,这样就只能由class来遵守了,代码大致如下:

@objc protocol TestDelegate {
  func testMethod()
}

2.在protocol的声明后面加上class,这样可以为编译器显式的指名这个protocol只能由class来遵守,代码大致如下:

// 更推荐这种方式,易于理解,更能表现出问题的实质
protocol TestDelegate: class {
  func testMethod()
}
上一篇下一篇

猜你喜欢

热点阅读