ここでいくつか質問した後、私は次のようなサーバーを実行することにしました。
@implementation Server
-(id)init
{
if (self = [super init])
{
shouldRun = true;
__block Server* blocksafeSelf = self; // should prevent retain cycle
myServer = ^() {
dispatch_async(dispatch_get_main_queue(), ^{
NSString* currentText = controller.output.text;
controller.outputTextField.text = [currentText stringByAppendingString:@"Server ready. \n"];
});
while (blocksafeSelf.shouldRun) {
int bytes_received = recvfrom(...);
if (bytes_received > 0) {
switch (TYPE OF RECEIVED PACKET) {
case 1: {
dispatch_async(dispatch_get_main_queue(), ^{
NSString* currentText = controller.outputTextField.text;
controller.outputTextField.text = [currentText stringByAppendingString:@"S: Received Typ 1 "];
});
[blocksafeSelf methodToDealWithPacket:(PACKETTYPE*) buffer];
break;
}
...
default: {
...
}
}
}
}
return self;
}
@synthesize shouldRun;
対応する.hファイル:
@interface Server : NSObject {
ServerBlock myServer;
....
}
@property BOOL shouldRun;
....
@end
これで、ViewControllerができました。これは、サーバーをプロパティとして持ち、その実装に次のメソッドがあります。
// called when the user clicks the stop button
- (IBAction) clickedStop
{
if(theServer != nil) {
theServer.shouldRun = false;
}
}
ただし、停止ボタンをクリックすると、サーバーはwhileループを終了しません。なんで?
編集:これは、ViewControllerでサーバーがどのように起動されるかです。
// called when the user clicks the start button
- (IBAction) clickedStart
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
if (...) { // all needed data has been entered
// start server here
if(theServer == nil) {
theServer = [[SNPTServer alloc] initWithHost:serverIP.text AndPort: [serverPort.text intValue] AndViewController:self];
dispatch_async(queue, theServer.myServer);
}
}
}
ご覧のとおり、コンストラクターを少し上に変更しました。