Seit NSOperation wird View nicht upgedated

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Seit NSOperation wird View nicht upgedated

    Hallo Forum,
    ich brauche Hilfe1

    Ich baue gerade an meiner ersten App und möchte mit einem Windows-SocketServer kommunizieren und Telegramme austauschen. Die Kommunikation funktioniert. Die Telegramme welche ausgetauscht werden, sind in einen Header und einen Datenbereich unterteilt. Der Datenbereich besteht aus einer Union. Die Telegramme beinhalten auch eine CheckSumme, die beim Erhalten des Telegramms berechnet und später kontrolliert wird. Da die Telegrammlänge durch die Union nun variable ist, muss meine Telegrammauswertung in einer Endlosschleife laufen, da ich ja nicht immer ein komplettes Telegramm aus dem Stream erhalte. Eventuell lese ich nur ein ganzes und ein halbes Telegramm aus. Beim nächsten Lesen des Streams wird dann der Rest des letzten Telegramms verarbeitet.
    Die While-Schleife, die das Auslesen aus dem Stream macht, wird über eine NSOperation und NSOperationQueu aus AppDelegatee gestartet.
    Beim Erhalt eines gültigen Telegramms wird dann eine NSNotification ausgelöst. Ein ViewController fängt diese Notification und ruft damit eine Methode auf, welche verschiedene NSLogs schreibt und den ViewController updaten soll.
    Dieses alles funktioniert:
    Es werden NSLogs mit den erwarteten Werten ausgegeben. _ Nur: Der ViewController wird NICHT upgedatet !!!
    Wenn ich den Empfang des Telegramms ohne NSOperation durchführe, funktioniert das Updaten des ViewControllers.

    Vielleicht hat jemand eine Idee?

    Hier mal der QuellcodeAuszug:

    Quellcode

    1. #import "AppDelegate.h"
    2. #import "Communicator.h"
    3. @interface AppDelegate ()
    4. @property Communicator *communicator;
    5. @end
    6. @implementation AppDelegate
    7. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    8. {
    9. // create, init and open communication
    10. self.communicator = [Communicator new];
    11. self.communicator->host = @"192.168.14.184";
    12. self.communicator->port = 700;
    13. self.communicator->clientIP = @"10.0.10.117";
    14. self.communicator->loggedInUser = @"Apple";
    15. self.communicator->stationName = @"iPhone5s";
    16. [self.communicator startCommunicator];
    17. // init communicator queue
    18. NSOperationQueue* communicatorQueue = [NSOperationQueue new];
    19. // start communicator
    20. [communicatorQueue addOperation:self.communicator];
    21. return YES;
    22. }
    Alles anzeigen


    Quellcode

    1. #import <UIKit/UIKit.h>
    2. @interface StoreUtilizationViewController : UIViewController
    3. @property (strong, nonatomic) IBOutlet UISlider *sliderUtilizationTotal;
    4. @property (strong, nonatomic) IBOutlet UISlider *sliderUtilizationZL1;
    5. @property (strong, nonatomic) IBOutlet UISlider *sliderUtilizationZL2;
    6. @property (strong, nonatomic) IBOutlet UISlider *sliderUtilizationRL;
    7. @property (strong, nonatomic) IBOutlet UILabel *labelStoreUtilizationTotal;
    8. @property (strong, nonatomic) IBOutlet UILabel *labelStoreUtilizationZL1;
    9. @property (strong, nonatomic) IBOutlet UILabel *labelStoreUtilizationZL2;
    10. @property (strong, nonatomic) IBOutlet UILabel *labelStoreUtilizationRL;
    11. @property (strong, nonatomic) IBOutlet UILabel *labelUpdateDescription;
    12. @property (strong, nonatomic) IBOutlet UILabel *labelProcentTotal;
    13. @property (strong, nonatomic) IBOutlet UILabel *labelProcentZL1;
    14. @property (strong, nonatomic) IBOutlet UILabel *labelProcentZL2;
    15. @property (strong, nonatomic) IBOutlet UILabel *labelProcentRL;
    16. @property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicatorView;
    17. @property (strong, nonatomic) IBOutlet UIProgressView *progressBarStoreUtilization;
    18. - (void) processTelegram: (NSNotification*) notifaction;
    19. @end
    Alles anzeigen


    Quellcode

    1. #import "StoreUtilizationViewController.h"
    2. #import "StoreUtilization.h"
    3. @interface StoreUtilizationViewController ()
    4. @property NSTimer* timer;
    5. @property int timerTick;
    6. @end
    7. @implementation StoreUtilizationViewController
    8. - (void)viewDidLoad
    9. {
    10. // set slider
    11. self.sliderUtilizationTotal.minimumValue = 0;
    12. self.sliderUtilizationTotal.maximumValue = 100;
    13. self.sliderUtilizationZL1.minimumValue = 0;
    14. self.sliderUtilizationZL1.maximumValue = 100;
    15. self.sliderUtilizationZL2.minimumValue = 0;
    16. self.sliderUtilizationZL2.maximumValue = 100;
    17. self.sliderUtilizationRL.minimumValue = 0;
    18. self.sliderUtilizationRL.maximumValue = 100;
    19. // set label
    20. self.labelStoreUtilizationTotal.text = @"Total:";
    21. self.labelStoreUtilizationZL1.text = @"Intermediate store 1:";
    22. self.labelStoreUtilizationZL2.text = @"Intermediate store 2:";
    23. self.labelStoreUtilizationRL.text = @"Back store:";
    24. self.labelProcentTotal.text = @"0 %";
    25. self.labelProcentZL1.text = @"0 %";
    26. self.labelProcentZL2.text = @"0 %";
    27. self.labelProcentRL.text = @"0 %";
    28. // start activityIndicatorView
    29. CGAffineTransform transform = CGAffineTransformMakeScale(2.0f, 2.0f);
    30. self.activityIndicatorView.transform = transform;
    31. [self.activityIndicatorView startAnimating];
    32. self.activityIndicatorView.hidden = NO;
    33. self.timerTick = 0;
    34. [self startTimer];
    35. // add observer
    36. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processTelegram:) name:@"STOREUTILIZATION" object:nil];
    37. }
    38. - (void) viewWillDisappear:(BOOL)animated {
    39. [super viewWillDisappear:animated];
    40. [self stopTimer];
    41. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"STOREUTILIZATION" object:nil];
    42. }
    43. -(void) processTelegram: (NSNotification*) notifaction
    44. {
    45. StoreUtilization *storeUtilization = [[notifaction userInfo] valueForKey:@"SEARCHKEY"];
    46. NSLog(@"###########################################################");
    47. NSLog(@"######### Received Notification - telegram = %d", [storeUtilization nTotal]);
    48. NSLog(@"######### Received Notification - telegram = %d", [storeUtilization nRL]);
    49. NSLog(@"######### Received Notification - telegram = %d", [storeUtilization nZL1]);
    50. NSLog(@"######### Received Notification - telegram = %d", [storeUtilization nZL2]);
    51. // set slider
    52. [self.sliderUtilizationTotal setValue:storeUtilization.nTotal animated:YES];
    53. [self.sliderUtilizationZL1 setValue:storeUtilization.nZL1 animated:YES];
    54. [self.sliderUtilizationZL2 setValue:storeUtilization.nZL2 animated:YES];
    55. [self.sliderUtilizationRL setValue:storeUtilization.nRL animated:YES];
    56. // set progress bar ticker
    57. self.timerTick = 0;
    58. // set label
    59. NSString *string = [NSString stringWithFormat:@"%d %%", storeUtilization.nTotal];
    60. self.labelProcentTotal.text = string;
    61. string = [NSString stringWithFormat:@"%d %%", storeUtilization.nZL1];
    62. self.labelProcentZL1.text = string;
    63. string = [NSString stringWithFormat:@"%d %%", storeUtilization.nZL2];
    64. self.labelProcentZL2.text = string;
    65. string = [NSString stringWithFormat:@"%d %%", storeUtilization.nRL];
    66. self.labelProcentRL.text = string;
    67. if( storeUtilization.nTotal > STOREUTILIZATION_RED )
    68. { self.labelProcentTotal.textColor = [UIColor redColor];
    69. }
    70. else if ( storeUtilization.nTotal > STOREUTILIZATION_YELLOW )
    71. { self.labelProcentTotal.textColor = [UIColor orangeColor];
    72. }
    73. else
    74. { self.labelProcentTotal.textColor = [UIColor blackColor];
    75. }
    76. if( storeUtilization.nZL1 > STOREUTILIZATION_RED )
    77. { self.labelProcentZL1.textColor = [UIColor redColor];
    78. }
    79. else if ( storeUtilization.nZL1 > STOREUTILIZATION_YELLOW )
    80. { self.labelProcentZL1.textColor = [UIColor orangeColor];
    81. }
    82. else
    83. { self.labelProcentZL1.textColor = [UIColor blackColor];
    84. }
    85. if( storeUtilization.nZL2 > STOREUTILIZATION_RED )
    86. { self.labelProcentZL2.textColor = [UIColor redColor];
    87. }
    88. else if ( storeUtilization.nZL2 > STOREUTILIZATION_YELLOW )
    89. { self.labelProcentZL2.textColor = [UIColor orangeColor];
    90. }
    91. else
    92. { self.labelProcentZL2.textColor = [UIColor blackColor];
    93. }
    94. if( storeUtilization.nRL > STOREUTILIZATION_RED )
    95. { self.labelProcentRL.textColor = [UIColor redColor];
    96. }
    97. else if ( storeUtilization.nRL > STOREUTILIZATION_YELLOW )
    98. { self.labelProcentRL.textColor = [UIColor orangeColor];
    99. }
    100. else
    101. { self.labelProcentRL.textColor = [UIColor blackColor];
    102. }
    103. // start activityIndicatorView
    104. [self.activityIndicatorView stopAnimating];
    105. self.activityIndicatorView.hidden = YES;
    106. //
    107. // Bis hier sind alle Variablen richtig gefüllt und es entsteht kein Fehler!!!
    108. //****************************************************************************************
    109. }
    110. - (void)startTimer
    111. {
    112. self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(tickProgressBar) userInfo:nil repeats:YES];
    113. }
    114. - (void)stopTimer
    115. {
    116. [self.timer invalidate];
    117. }
    118. - (void)tickProgressBar
    119. {
    120. self.timerTick++;
    121. if (self.timerTick <= 30)
    122. { self.progressBarStoreUtilization.progress = (float) self.timerTick / 30.0f;
    123. }
    124. else
    125. { self.progressBarStoreUtilization.progress = 0;
    126. self.timerTick = 0;
    127. }
    128. }
    129. - (NSUInteger) supportedInterfaceOrientations
    130. {
    131. return UIInterfaceOrientationMaskPortrait;
    132. }
    133. @end
    Alles anzeigen
  • Erst mal Danke für die Antworten!
    Ich hab im AppDelegate mal folgendes If eingefügt

    if ([NSThread isMainThread]) {
    NSLog(@"ok. this is main thread. AppDelegate");
    } else {
    NSLog(@"don't call this method from other thread! AppDelegate");
    }

    Hier kommt die Info, dass AppDelegate der MainThread ist. So hatte ich es auch gehofft.
    Was ich jetzt nicht verstehe ist. Da die Methode processTelegram in der Klasse des ViewContollers ist. Ist dann nicht auch sichergestellt, dass diese Klasse mit deren Methoden auch im MainThrad, wie auch AppDelegate ist?

    Muss ich vielleicht eine Notification vom EmpfangsThread zum AppDelegate machen und danach noch einmal eine Notification vom AppDelegate zur Klasse des ViewControllers?
    Wäre ja ein wenig umständlich...
  • Michael_1965 schrieb:

    Da die Methode processTelegram in der Klasse des ViewContollers ist. Ist dann nicht auch sichergestellt, dass diese Klasse mit deren Methoden auch im MainThrad, wie auch AppDelegate ist?

    Nein, die Klasse einer Methode hat nichts damit zu tun, in welchem Thread sie ausgeführt wird. Die Ausführung im Main-Thread ist jedoch sehr einfach, z. B.:

    Quellcode

    1. dispatch_async(dispatch_get_main_queue(), ^{
    2. // Code hier einfügen
    3. });
    „Meine Komplikation hatte eine Komplikation.“
  • Ich hab noch eine Info:
    Die oben gezeigte If-Abfrage sagt auch der ViewController liegt im Main-Thread.
    In dieser Klasse ist auch die Methode processTelegram die die Controls im ViewControler updaten soll.

    Liegt es vielleicht an dem Aufruf:
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processTelegram:) name:@"STOREUTILIZATION" object:nil];
    Ist hier was falsch?