Как получить доступ к состоянию моего приложения (классы, свойства и т. Д.) После обратного вызова из CFStream? - PullRequest
0 голосов
/ 13 марта 2011

Я пишу приложение для iPhone, которое включает обработку сетевых событий с сервера через VoIP-сокет в фоновом режиме. Я успешно настроил сокет, информацию о фоновом сервисе в .plist и соответствующие потоки, но мне трудно понять, как сделать что-нибудь полезное в моем обратном вызове. Я не знаю, как получить доступ к остальной части состояния моего приложения из функции обратного вызова. Вот где я настраиваю соединения в AppDelegate:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    NSLog(@"AppDelegate: didFinishLaunchingWithOptions");
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream;
    CFHostRef host = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)@"irc.freenode.net");
    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, host, 6667, &readStream, &writeStream);
    CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
    CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);

    CFStreamClientContext myContext = {
        0,
        viewController,
        (void *(*)(void *info))CFRetain,
        (void (*)(void *info))CFRelease,
        (CFStringRef (*)(void *info))CFCopyDescription
    };

    CFOptionFlags registeredEvents = kCFStreamEventHasBytesAvailable |
    kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;

    if(CFReadStreamSetClient(readStream, registeredEvents, clientCB, &myContext)) {
        CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
    }

    if (!CFReadStreamOpen(readStream)) {
        NSLog(@"Read stream could not be opened");
    }
    else {
        NSLog(@"Successfully opened read stream");
    }
    return YES;
}

А вот функция обратного вызова для событий CFStream, где у меня возникают проблемы:

void clientCB(CFReadStreamRef stream, CFStreamEventType event, void* myPtr) {
    switch(event) {
        case kCFStreamEventHasBytesAvailable:{
            UInt8 buf[32];
            CFIndex bytesRead = CFReadStreamRead(stream, buf, 32);
            if (bytesRead > 0) {
                NSLog(@"Readstream Not Empty %i", buf[0]);//dummy debug marker
            }
            //I WANT TO ACCESS CLASSES, PROPERTIES, FUNCTIONS, ETC. ABOUT THE REST OF MY PROGRAM HERE (E.G. GET A WORKING POINTER BACK TO THE MAIN APPDELEGATE).
        break;
    }
    case kCFStreamEventErrorOccurred:
    case kCFStreamEventEndEncountered:
    default:
        break;
}
}

Эти две функции определены в одном и том же классе AppDelegate. Я попытался передать указатели через структуру CFStreamClientContext: VoIP_TestViewController* testViewController = context->info;, я попытался получить доступ к основному appDelegate через: [[UIApplication sharedApplication] delegate], и я попробовал обычные конструкции Obj-C и C ("this", "self" "," супер ").

Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

0 голосов
/ 15 марта 2011

Ах, я идиот.Я забыл импортировать заголовок класса для класса члена (т.е. я забыл импортировать ClassB, когда пытался получить доступ к [ClassA.ClassB methodB]).Конечно, XCode предоставил только нераспознанную ошибку времени выполнения селектора, а не пропущенную ошибку компилятора объявления, что сделало отладку немного сложнее, чем следовало бы.Спасибо за улов!

0 голосов
/ 13 марта 2011
  1. Убедитесь, что вы импортировали файл заголовка основного делегата приложения в представление, где его нужно вызвать.

  2. Используйте это, чтобы назвать это:

nameOfYourAppDelegate * appDelegate = (_nameOfYourAppDelegate *) [[UIApplication sharedApplication] делегат];

// чем вы можете использовать appDelegate для чего угодно (т.е. appDelegate.somView.someProperty)

...