2011-07-27 11 views
5

tanınmayan seçici ile çöker. protokole Sınıfımdan bağlamaya, özel protokolünün uygulanması Özel bir protokolü tanımlayan am

@interface NGSFacebookAuthProvider : NSObject <NGSAuthProvider> 
@end 

@interface NGSFacebookAuthProvider() <FBSessionDelegate> 
@property BOOL ready; 
@property(nonatomic, retain) Facebook *facebook; 
@property(nonatomic, retain) NSArray *permissions; 
@end 

@implementation NGSFacebookAuthProvider 
//Implementation of fbLogin, fbLogout and the methods in NGSAuthProvider that forward calls to self.facebook 
- (NSString *)accessToken 
{ 
    return [self.facebook accessToken]; 
} 

@end 

Ben kurulum Objection: Yani bir bir Facebook sağlayıcıdır.

@interface NGSObjectionModule : ObjectionModule 
@end 

@implementation NGSObjectionModule 

- (void)configure 
{ 
    self bind:[NGSFacebookAuthProvider class] toProtocol:@protocol(NGSAuthProvider)]; 
} 
@end 

Ben kurulum Küresel Enjektör:

@implementation NGSAppDelegate 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    ObjectionModule *module = [[NGSObjectionModule alloc] init]; 
    ObjectionInjector *injector = [Objection createInjector:module]; 
    [module release]; 

    [Objection setGlobalInjector:injector]; 
} 

Bu gibi benim RootViewController bu kullanıyorum:

@interface RootViewController : UITableViewController 
@end 

@interface RootViewController() 
@property(nonatomic, retain) id<NGSAuthProvider> authProvider; 
@end 

@implementation RootViewController 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.authProvider = [[Objection globalInjector] getObject:@protocol(NGSAuthProvider)]; 
} 

- (void)processConfig { 
    NSString *token = [self.authProvider accessToken]; 
    // use the access token 
} 
@end 

ben bu çalıştırdığınızda, aşağıdaki hatayı alıyorum:

2011-07-26 21:46:10.544 ngs[6133:b603] +[NGSFacebookAuthProvider accessToken]: unrecognized selector sent to class 0x30c7c 
2011-07-26 21:46:10.546 ngs[6133:b603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NGSFacebookAuthProvider accessToken]: unrecognized selector sent to class 0x30c7c' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x00e825a9 __exceptionPreprocess + 185 
    1 libobjc.A.dylib      0x00fd6313 objc_exception_throw + 44 
    2 CoreFoundation      0x00e8417b +[NSObject(NSObject) doesNotRecognizeSelector:] + 187 
    3 CoreFoundation      0x00df3966 ___forwarding___ + 966 
    4 CoreFoundation      0x00df3522 _CF_forwarding_prep_0 + 50 
    5 ngs         0x0000324b -[RootViewController processConfig] + 731 
    6 ngs         0x000041a2 __33-[RootViewController viewDidLoad]_block_invoke_0 + 50 

Yani benim sınıfım protokolü tamamlar. Bu başarıyla id<NGSAuthProvider>'a atandı. Objection'u kullanmak yerine [[NGSFacebookAuthProvider alloc] init]'u açıkça denedim ve hala çöktü.

- (void)logSelectors:(id)obj 
{ 
    int i=0; 
    unsigned int mc = 0; 
    Method * mlist = class_copyMethodList(object_getClass([obj class]), &mc); 
    NSLog(@"%d methods", mc); 
    for(i=0;i<mc;i++) 
     NSLog(@"Method no #%d: %s", i, sel_getName(method_getName(mlist[i]))); 

    free(mlist); 
} 

Bu ben eksik basit bir şey olmalı:

Ben seçicileri var ama bulduğu tek şey initialize olduğunu görmek için objc/runtime.h yöntemlerle seçicileri arasında döngü çalıştı. Kakao tarafından tanımlanan protokolleri kullanıyorum ve bu konuya sahip değilim. Sorun olmadan UIViewController tabanlı delege için özel protokoller tanımladı.

Obj-C çalışma zamanımın yöntemlerimi bulamaması konusunda çok şaşırdım! id<NGSAuthProvider>'u NGSFacebookAuthProvider olarak değiştirir ve açıkça yapılandırırsanız, her şey çalışır.

ÇÖZÜM: Sorun bir protokole bağlamak nasıl yanlış

oldu. işleri Tek yoludur:

@implementation NGSObjectionModule 

- (void)configure 
{ 
    [self bind:[[[NGSFacebookAuthProvider alloc] init] autorelease] toProtocol:@protocol(NGSAuthProvider)]; 
} 
@end 

Ben bir protokol için bir sınıf bağlamak yapmak istiyorum ne ama İtiraz muhtemelen başlatıcı aramak bilemeyiz?

+0

aynı sorunla karşı karşıya, ben [anılacaktır http://ravelantunes.com/blog/ olgun bağımlılık enjeksiyon /]. Ancak [- (void) { [self bind: [MyUserService sınıfı] toProtocol: @protocol (UserService)] öğesini yapılandırır; }], Tanımlama sınıfında bir Hata var. Çözümünüz işe yaradı !!!! –

cevap

0

Sorun, nesnesinin bir örneğinde çalıştırılan bir yöntem yerine statik sınıf yöntemini (bir + sahip olduğunuz anlamına gelir) kullanmaya çalışmaktır (bu, yazdığınız gibi) a -)

+0

Sınıf yöntemini nerede kullandığımı göremiyorum. – chrish

+0

Ben de. Ama bir şekilde sen, değil mi? Belki de bir nesnenin bir örneğinizin olduğunu düşünürsünüz, fakat bu türün kendisinin bir işaretçisidir (sınıf yöntemlerinin üstlendiğim kaput altında nasıl çalışır) – Nektarios

+1

Statik bir sınıf yönteminin çağrılması hakkında yorum yapmak beni düşünmemi sağladı. Sorun, İtirazı nasıl yapılandıracağım. Bir protokol için talep edildiğinde bir örneği başlatmak için bir sınıf nesnesi kullanmak için kurduğumu düşündüm. Yapılandırırken gerçekten bir örnek oluşturmak zorundayım. Soruyu dahil etmek için soruyu güncelleyeceğim. Şimdi hata ayıklama çıktısında '+ [NGSFacebookAuthProvider accessToken]' ı bulamadığını görüyorum. – chrish

0

Chris

sen bir protokole meta sınıf bağlamak ve meta sınıf örneğine karşı sınıf yöntemleri çağırmak için izin verdiğini itirazı meta sınıf bağlamaları kullanabilirsiniz. Örneğin

,

[self bindMetaClass:[NGSFacebookAuthProvider class] toProtocol:@protocol(NGSAuthProvider)]; 

Ama sadece sınıf yöntemleri kullanmak istiyorum. Aksi halde protokol bağlarını bir paylaşım örneğine karşı kullanabilirsiniz.Ben

kullanıyordum olarak
+0

Neden sınıf nesnesine bir protokolü bağlayacağınızdan pek emin değilim. Yani sınıf nesnesi protokolü uygulamak zorunda mı? – chrish

+0

Protokol, arabirimi yansıtır (aslında bunu yapmak zorunda değildir, ancak meta sınıfının yoksa derleyici uyarıları alırsınız). Protokol basitçe bir bağlanma mekanizması olarak hareket eder, böylece Objection bir nesneyi bir nesneye nasıl bağlayacağını bilir. Meta sınıfının arayüzünü yansıtan bir özelliği tanımlamanın bir yolu olmadığı için protokol bunu yapmak için kullanılır. Bkz. Https://github.com/atomicobject/objection ve meta sınıfı ciltleme bölümünü okuyun. – justice

+0

Tamam, istediğim bu değildi (yani sınıf yöntemleri). Ben NGSAuthProvider protokolü birkaç farklı uygulamaları vardı ve ben bir protokol için talep edildiğinde belirli bir sınıfın bir örneğini oluşturmak için İtiraz yapılandırmak istedim. Bu yüzden “self bind: [NGSFacebookAuthProvider class] toProtocol: @protocol (NGSAuthProvider)] 'ın Objection'ın bir NGSFacebookAuthProvider örneğini oluşturmasına neden olmasını istedim ama bunun yerine sınıf nesnesini sağladı. – chrish

0

Ben de
[self bind:[MyClass class] toProtocol:@protocol(MyProtocol)]; 

işe yaraması için doğru yol Merhaba

[self bindClass:[MyClass class] toProtocol:@protocol(MyProtocol)]; 
İlgili konular