0

私は目的の c を初めて使用します (.NET 開発から iPhone への移行)。さて、iPhone 開発の経験がある方に簡単な質問があります。audiotoolbox を使用していくつかのオーディオ イベントに反応する静的ライブラリを作成しています。私のヘッダーは次のようになります。

@interface ccreaderlib : NSObject {
    id __unsafe_unretained delegate;
    SEL _DevicePluggedEvent;
    SEL _DeviceUnpluggedEvent;

}

@property (nonatomic, assign) id delegate;
@property (nonatomic, assign) SEL onDevicePlugged;
@property (nonatomic, assign) SEL onDeviceUnplugged;


- (id)init;
- (void)startMonitor;
- (void)stopMonitor;


@end

今UIViewControllerで私はこれをやっています:

_lib = [[ccreaderlib alloc] init];
    _lib.delegate = self;
    _lib.onDevicePlugged = @selector(OnDevicePluggedIn);
    _lib.onDeviceUnplugged = @selector(OnDeviceUnplugged);
[_lib startMonitor];

私のアイデアは、静的ライブラリから UIViewController のセレクターを呼び出すことです。これどうやってするの。現時点では、私はこの方法でこれをやろうとしています:

void audioRouteChangeListenerCallback (
                                       void                      *inUserData,
                                       AudioSessionPropertyID    inPropertyID,
                                       UInt32                    inPropertyValueSize,
                                       const void                *inPropertyValue) 
{
    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;

CFDictionaryRef routeChangeDictionary = inPropertyValue;
CFNumberRef routeChangeReasonRef =
CFDictionaryGetValue ( routeChangeDictionary, CFSTR (kAudioSession_AudioRouteChangeKey_Reason));
SInt32 routeChangeReason;
CFNumberGetValue (
                  routeChangeReasonRef,
                  kCFNumberSInt32Type,
                  &routeChangeReason);

CFStringRef oldRouteRef =
CFDictionaryGetValue (
                      routeChangeDictionary,
                      CFSTR (kAudioSession_AudioRouteChangeKey_OldRoute));
NSString *oldRouteString = (__bridge NSString *)oldRouteRef;
ccreaderlib *self = (__bridge id)inUserData;
id reactClass = [self delegate];
if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable)
{
    if ([oldRouteString isEqualToString:@"Speaker"])
    {
        [reactClass performSelector:@selector(onDevicePlugged)];
        self.bIsReaderPlugged = YES;
    }


}
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
    if ([oldRouteString isEqualToString:@"Headphone"]){
        [reactClass performSelector:@selector(onDeviceUnplugged)];
        self.bIsReaderPlugged = NO;
    }
}

}

しかし、このようにしてSIGABRTを取得します。私を助けてください、これを解決しようとしてすでに3日を費やしました。

***更新: 自分で答えを見つけました。私のCコールバック関数を次のように変更しました:

if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable)
{
    if ([oldRouteString isEqualToString:@"Speaker"])
    {
        if([self.delegate respondsToSelector:self.onDevicePlugged])
            [self.delegate performSelector:self.onDevicePlugged];
        self.bIsReaderPlugged = YES;
    }


}
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
    if ([oldRouteString isEqualToString:@"Headphone"]){
        if([self.delegate respondsToSelector:self.onDeviceUnplugged])
            [self.delegate performSelector:self.onDeviceUnplugged];
        self.bIsReaderPlugged = NO;
    }
}

http://brandontreb.com/objective-c-programming-tutorial-creating-a-twitter-client-part-1/に感謝します

4

2 に答える 2

1

これは委任の非常に特殊なパターンです。通常、プロトコルを宣言します。

@protocol(DevicePlugDelegateP)
- (void)pluggedInDevice:(Device*)aDevice;
- (void)unpluggedDevice:(Device*)aDevice;
@end

次に、デリゲートを次のように宣言します。

__weak NSObject<DevicePlugDelegateP>* delegate;

次に、セレクターの応答を確認し、存在する場合はそれを呼び出します。

if ([delegate respondsToSelector:@selector(pluggedInDevice:)])
    [delegate pluggedInDevice:aDevice];

...など...

あなたがしていることは間違っているわけではありません。上記のパターンにより、どのクラスがその特定のデリゲートとして機能できるかが非常に明確になり、後で 1 つのメソッド実装を検索すると、誰がどのメソッドを実装しているかが明らかになります。

于 2012-07-21T18:21:33.203 に答える
1

スペルが正しいですか - 場合によっては大文字で表示され、他の場合ではそうではありません (最初の「o」)。

クラスで最初に行うべきことは、デリゲートが実際にセレクターに応答することを確認することです。

BOOL [delegate repondsToSelector:your_selector_variable];
BOOL [delegate respondsToSelector:@selector(TheActualSelector)]; // don't forget trailing ':' if it takes an arg

これを正しく理解していない場合は先に進む理由がないため、開発中にこれらについて断言します。

于 2012-07-21T12:32:09.583 に答える