2016-08-28 11 views
1

난 단지 기능을 사용하여 신속의 옵저버 패턴을 구현하기 위해 노력하고있어 :스위프트, 폐쇄와 옵저버 패턴

var closures: [() -> Void] = [] 

class A: NSObject 
{ 
    static var c = 0 
    var i = 0 

    override init() 
    { 
     super.init() 
     self.i = A.c 
     A.c += 1 
    } 

    func foo() 
    { 
     print("Hi: \(i)") 
     print("\(A.c)") 
    } 
} // class 

var aa:A? = A() 

closures.append(aa!.foo) 

for item in closures 
{ 
    item() 
} 

aa = A() 

for item in closures 
{ 
    item() 
} 

이 인쇄 :

Hi: 0 
1 
Hi: 0 
2 

첫 번째 질문, 그것은 인스턴스 변수처럼 보인다 i이 수정되지 않은 이유는 무엇입니까?

두 번째 질문은 메모리가 누출됩니까? 배열 기능을 가지고 있기 때문에 배열을 비우지 않고 aa을 출시 할 예정입니까?

세 번째 질문, 그냥 함수를 사용하여 Observe 패턴에 대한 더 좋은 아이디어? (프로토콜을 사용하고 싶지 않습니다.)

답변

0

Google에서 더 나은 키워드를 사용하여 해결책을 찾았습니다. 프로토콜을 피하기 위해 클로저를 사용하여 관찰자 패턴을 구현하여 관찰자를 관찰 가능 객체와 분리해야했습니다. var array:[() ->()] = []

각 관찰 , 그것은이 배열 기능의 추가가 필요한 경우, 관찰자는 각각 또는이 배열의 어떤 함수를 호출한다 : 관찰자 이와 같은 클로저의 배열 목적으로한다. 기능은 다음과 같습니다.

lazy var someClosure:() -> String = { [unowned self, ] in // closure body goes here }

selfunowed 또는 weak으로 캡처해야 사이클을 유지하지 않도록합니다. https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4

1

보유/릴리스주기를 잘못 이해했습니다. 코드별로 한 줄씩 살펴 보겠습니다. A의 새 인스턴스를 초기화하십시오.

var aa:A? = A() 

이 메모리는 closures 배열 A의 인스턴스를 추가 1.

closures.append(aa!.foo) 

를 유지할 수있다. 테인 수는 A의 첫 번째 인스턴스 2.

for item in closures 
{ 
    item() 
} 

전화 foo입니다.

aa = A() 

A의 다른 인스턴스를 만듭니다. 첫 번째 인스턴스는 계속 어레이에 보관되고 보유 수는 1로 줄어 듭니다. 그러나 A.cinit 방법으로 코드화했기 때문에 증가합니다.

for item in closures 
{ 
    item() 
} 

여전히 첫 번째 개체에서 메서드를 호출하고 있습니다. A.c은 두 번째 개체와 공유되지만 i은 공유되지 않습니다. 두 번째 개체는 closures 배열에 없습니다.

다른 질문이 있기 전에 : 왜 시도하고 있습니까?

+0

나는 '왜'는 '무엇을'추측 : 여기

은 자세한 내용과이 솔루션을 exaplain 기사입니다.형식을 사용하지 않고 Observer 패턴을 구현하려고합니다. 클래스의 A와 같은 객체는 배열에 함수를 추가합니다. 필요한 경우 배열의 각 함수가 호출됩니다. 프로토콜을 사용하여 동일한 작업을 수행 할 수 있지만 다른 것을 시도하려고했습니다. – AR89