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ı:
- "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. 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ı veinvokeBlock:
yöntemi olarak hedef ve eylem (normal olarak).UIControl
kategoriUIControl
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.Biz sağlanması Aslında associated objects are cleaned up automatically during deallocation.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 orijinaldealloc
kodu. Zor, zor.
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ş:
Nasıl Objective-C ile çalışma zamanınd...
Objective-C blok özellikleri olarak ku...
Neden kısa, ama int değişken değil ben...
Java'da değişken bağımsız değişken bir...
Nasıl dosyaları zaman uyumsuz olarak y...