SORU
3 Ocak 2011, PAZARTESİ


Bir @Objective-C ile seçici olarak bloke geçebilir miyim?

UIButton @selector değişken için Objective-C blok geçmek mümkün mü? yani, çalışmak için aşağıdaki almak için herhangi bir yolu var mı?

    [closeOverlayButton addTarget:self 
                           action:^ {[anotherIvarLocalToThisMethod removeFromSuperview];} 
                 forControlEvents:UIControlEventTouchUpInside];

Teşekkürler

CEVAP
3 Ocak 2011, PAZARTESİ


Evet, ama bir kategori kullanmak zorunda olurdu.

Gibi bir şey

@interface UIControl (DDBlockActions)

- (void) addEventHandler:(void(^)(void))handler 
        forControlEvents:(UIControlEvents)controlEvents;

@end

Uygulaması biraz zor olabilir:

#import <objc/runtime.h>

@interface DDBlockActionWrapper : NSObject
@property (nonatomic, copy) void (^blockAction)(void);
- (void) invokeBlock:(id)sender;
@end

@implementation DDBlockActionWrapper
@synthesize blockAction;
- (void) dealloc {
  [self setBlockAction:nil];
  [super dealloc];
}

- (void) invokeBlock:(id)sender {
  [self blockAction]();
}
@end

@implementation UIControl (DDBlockActions)

static const char * UIControlDDBlockActions = "unique";

- (void) addEventHandler:(void(^)(void))handler 
        forControlEvents:(UIControlEvents)controlEvents {

  NSMutableArray * blockActions = 
                 objc_getAssociatedObject(self, &UIControlDDBlockActions);

  if (blockActions == nil) {
    blockActions = [NSMutableArray array];
    objc_setAssociatedObject(self, &UIControlDDBlockActions, 
                                        blockActions, OBJC_ASSOCIATION_RETAIN);
  }

  DDBlockActionWrapper * target = [[DDBlockActionWrapper alloc] init];
  [target setBlockAction:handler];
  [blockActions addObject:target];

  [self addTarget:target action:@selector(invokeBlock:) forControlEvents:controlEvents];
  [target release];

}

@end

Bunun bir açıklaması:

  1. "Sadece iç" DDBlockActionWrapper sınıf denir. özel kullanıyoruz Bu blok bir özellik (çağrılan almak istiyoruz blok), ve sadece o blok çağıran bir yöntem olan basit bir sınıftır.
  2. UIControl kategori basitçe başlatır bunlardan sarma, veren engellemek için çağrılabilir, ve o diyor kendisi için kullanan sarıcı ve invokeBlock: yöntemi olarak hedef ve eylem (normal olarak).
  3. UIControl kategori UIControl hedeflerini korumaz çünkü DDBlockActionWrappers, bir dizi saklamak için ilişkili bir nesne kullanır. Bu dizi blokların çağrılması gerekiyordu zaman var emin olmak için.
  4. Biz sağlanması DDBlockActionWrappers temizlerken nesne yok, bu yüzden biz yapıyoruz, kötü bir hack'in swizzling -[UIControl dealloc] ile yeni bir o kaldırır ilişkili nesne ve sonra çağırır orijinal dealloc kodu. Zor, zor.Aslında associated objects are cleaned up automatically during deallocation.

Son olarak, bu kod, tarayıcıda yazılmış ve derlenmiştir. Muhtemelen bazı şeyler yanlış vardır. Sizin kilometre değişebilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ben Vivona

    Ben Vivona

    24 Ocak 2010
  • DigitalRev TV

    DigitalRev T

    30 AĞUSTOS 2007
  • Tom Megalis

    Tom Megalis

    18 NİSAN 2006