2011-10-27 17 views
5

benim ortamında böyle bir şey kurmak istiyorum.Bir kakao Bildiriminden c işlevi işaretçisinin çağrılmasına nasıl trambolin yapılır?

[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self 
    forKeyPath:[@"values." stringByAppendingString: @"MyPreference"] 
    options:NSKeyValueObservingOptionNew 
    context:NULL]; 

Bunu bir Smalltalk ortamından yapıyorum. Özellikle Smalltalk, yukarıdakileri objektif çalışma zamanı özelliklerini kullanarak sürdürebilir. Sorun, addObserver: argümanı olarak "ben" dir. Smalltalk'dan, Smalltalk'a geri arama işlevi görecek bir C işlevi işaretçisi oluşturabilirim. Ancak ObjectiveC ortamına bir Object'in ne olduğu hakkında bir fikir sunamaz.

Yani Oluşturduğum fonksiyon işaretçisi yürütülecek neden uygun API ile nesnenin bir çeşit trambolin anlamaya çalışıyorum. NSInvokation ve arkadaşlarına baktım, ancak bunların hiçbiri C işlevi işaretçisinin etrafına sarmak için kullanılmadı. Ve doğru olanı yapmak için addObserver:forKeyPath:options:context:'u çevireceklerinden emin değilim.

soru Herhangi bir yeni objc kod derleme olmadan C işlev işaretçisi yürütülmesi olan bir Bildirimi bir yanıt kaydetmek için mevcut Kakao nesneleri kullanmak, nasıl aşağı Haşlanmış.

cevap

2

Sen Objective-C bir tutkal sınıf oluşturmak gerekir. Bunu yapabilirdi:

typedef void TravisGriggsCallback(); 

@interface TravisGriggsGlue { 
    TravisGriggsCallback *_callback; 
} 
- (id)initWithCallback:(TravisGriggsCallback *)callback; 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
    change:(NSDictionary *)change context:(void *)context 
@end 

@implementation TravisGriggsGlue 

- (id)initWithCallback:(TravisGriggsCallback *)callback 
{ 
    if (!(self = [super init])) 
     return nil; 
    _callback = callback; 
    return self; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
    change:(NSDictionary *)change context:(void *)context 
{ 
    _callback(); 
} 

@end 

Eğer callback'inde argüman geçmek gerekiyorsa, argümanlar tutmak için örnek değişkenler ekleyebilir ve init yöntemine onları geçmeniz gerekir.

Sonra bu gibi kullanmak:

TravisGriggsGlue *glue = [[TravisGriggsGlue alloc] 
    initWithCallback:&someCallbackFunction]; 
[[NSUserDefaultsController sharedUserDefaultsController] 
    addObserver:self 
    forKeyPath:[@"values." stringByAppendingString: @"MyPreference"] 
    options:NSKeyValueObservingOptionNew 
    context:NULL]; 
[glue release]; // only needed if not using ARC 
0

basit fonksiyon nesnesini kullanın:

@interface MONFunctor : NSObject 
- (void)performFunction; 
@end 

Sonra sadece gerektiği gibi uzmanlaşmak:

@interface MONFunctorSpecialization : NSObject 
{ 
@private 
// data, state, arguments for function, function pointer... 
} 
- (void)performFunction; 
@end 

Bir dinleyici olarak functor kullanabilirsiniz, ama senin dinleyici sadece olurdu sanki bu taslağını geri aramada [functor performFunction]; deyin.

Geriye

, bir sınıf olarak MONFunctor için gerek yoktur; bir protokol yeterli olur.

+0

Bu maalesef bana yardımcı olmuyor Justin. Yeni ObjC sınıfları oluşturamıyorum. Sadece objc çalışma zamanının ortaya çıktığı mevcut olanları kullanın. –

+0

@Travis ah! Bunun da kısıtlama olduğunu anlamadım. – justin

1

Ben kullandığınız Smalltalk hangi tür biliyorum ama Pharo içinde/muhtemelen ObjectiveCBridge eklentisi kullanıyorsanız gıcırtı yok. Bu durumda, bir ObjectiveCSqueakProxy dosyasını genişletebilir ve kakaodan kendi uygulamanıza verilen bir nesne olarak kullanabilirsiniz.

Bunun sizin için çalışıyorum umuyoruz.

İlgili konular