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

  • joshsnice

    joshsnice

    28 Kasım 2006
  • KarnasCamillo

    KarnasCamill

    24 EKİM 2007
  • Lamarr Wilson

    Lamarr Wilso

    27 Aralık 2008