7

Bir ObjectiveC++ projem var. ObjectiveC bağlamında ARC ve iPhoneSDK 6 kullanıyorum. C++ bir C++ 11 derleyici kullanıyorum.ARC ObjectiveC++ uygulamasında C++ 11 lambda işlevlerini kullanma - nasıl düzgün yapılır?

C++ 11'deki lambda işlevleri, değişkenlerle değişkenleri yakalar. Bu konsept gerçekten ObjectiveC tarafından desteklenmiyor ve "try and error" ile aşağıdaki çözümden geldim. Farkında değilim herhangi bir tuzak var mı?

Bu sorun için daha iyi bir çözüm var mı?

typedef std::function<void()> MyLambdaType; 

... 
// m_myView will not go away. ARC managed. 
UIView * __strong m_myView; 

... 
// In Objective C context I create a lambda function that calls my Objective C object 
UIView &myViewReference = *m_myView; 
MyLambdaType myLambda = [&myViewReference]() { 
    UIView *myViewBlockScope = &myViewReference; 
    // Do something with `myViewBlockScope` 
} 

.. 
// In C++11 context I call this lambda function 
myLambda(); 
+0

Neden bir blok kullanmıyorsunuz? – kennytm

+0

AFAIK blokları yalnızca ObjectiveC'dir, veya? Bir bloğu C++'ya nasıl geçirebilirim? –

+0

Does MyLambdaType myLambda = [m_myView]() {// m_myView ile bir şey yap}} çalışmıyor? – newacct

cevap

12

izin olurdu yapılacak basit şey lambda yakalama nesne işaretçisi değişkeni m_myView (Bu yerel bir değişken olduğunu Snippet'inizdeki gelen varsayıyorum) ve lambda içine normalde kullanmak:

MyLambdaType myLambda = [m_myView]() { 
    // Do something with `m_myView` 
} 

Tek endişe, m_myView bellek yönetimi olacaktır. Genel olarak doğru olması için, lambda, oluşturulduğunda m_myView'u korumalı ve yok olduğunda bırakın (bloklar gibi; çünkü lambda, m_myView'un bulunmadığı bir alanda kullanılabilir).

ARC belgelerini okumak, özellikle bu durumun söz konusu olduğunu görmüyorum, ancak bunun düzgün bir şekilde ele alması gerektiğine inanıyorum çünkü (1) C++ 11 lambda yakalanan değişkenler anonim alanlar olarak saklanır. lambda inşa edildiğinde yakalanan değere ilklendirilen sınıf, ve (2) ARC, C++ sınıflarının Objective-C nesne alanlarının inşası ve bırakılmasını, inşaat ve imha üzerine düzgün bir şekilde ele alır. Aksi halde lambdas hakkında özel bir şey söylemediği sürece, ya da bir derleyici hatası varsa, neden işe yaramayacağına dair bir sebep göremiyorum.

+4

Bu kesinlikle işe yarıyor. Zor olan şey, C++ 11 lambda terminolojisinde, 'm_myView' burada "değer" ile ele geçiriliyor. Eğer "referans" ile yakalarsanız (bunun gibi: '[& m_myView]() {...}') 'm_myView' nesnesini * NOT * ARC tarafından tutulur. Bunun hakkında düşünürseniz, bu mükemmel bir anlam ifade eder (yani, C++ 'yı' m_myView 'komutunu referans alarak yakaladığınızda, C++ bir * işaretçiye * referansı yakalar, nesneye bir referans değil) fakat terminoloji biraz kafa karıştırıcı olabilir. . – ipmcc

+0

@ipmcc: Evet. Bu, genel olarak C++ 11 lambdalarda referans olarak ele alınması için geçerlidir. C++ 11 lambda'da referans olarak yakalarsanız, o lambda'yı bu yakalanan değişkenlerin kapsamı dışında kullanamazsınız. – newacct

+0

m_myView tarafından kullanılan bellek ARC tarafından yayınlanmadı gibi görünüyor. Kodumda her birkaç milisaniye bir çok geri arama alıyorum ve hafızam sürekli olarak zıplıyor. Lambda işlevi içinde oluşturulan Objective-C nesneleri için aynıdır. Onlar da sızıyorlar. –