objective-c下,cocatouch框架把原生的socket做了进一步的封装,也就是stream.
添加CFNetwork框架
初始化套接字
CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"127.0.0.1", 7777, &readStream, &writeStream); inputStream = ( NSInputStream *)readStream; outputStream = ( NSOutputStream *)writeStream; [inputStream setDelegate:self]; [outputStream setDelegate:self]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream open]; [outputStream open];消息处理
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { NSLog(@"stream event %i", streamEvent); NSLog(@"%@",theStream); switch (streamEvent) { case NSStreamEventOpenCompleted: NSLog(@"Stream opened"); break; case NSStreamEventHasBytesAvailable: if (theStream == inputStream) { uint8_t buffer[1024]; int len; while ([inputStream hasBytesAvailable]) { len = [inputStream read:buffer maxLength:sizeof(buffer)]; if (len > 0) { NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; if (nil != output) { NSLog(@"server said: %@", output); [self messageReceived:output]; } } } } break; case NSStreamEventErrorOccurred: NSLog(@"Can not connect to the host!"); break; case NSStreamEventEndEncountered: [theStream close]; [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [theStream release]; theStream = nil; break; default: NSLog(@"Unknown event"); } }
想到要如何为所有的对象增加实例变量吗? 使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量(有为此使用查表法的,也算曲线救国吧)。不过从Mac OS X v10.6开始,系统提供了Associative References,这个问题就很容易解决了。
我根据Objective-C Reference中的示例修改了一下,直接上代码了。重点是其中objc_setAssociatedObject的使用, 并且其中Key是一个地址,而不是字串。
#import <Foundation/Foundation.h> #import <objc/runtime.h> int main (int argc, const char * argv[]) { @autoreleasepool { /*Seciton 0. 关联数据的Key和Value*/ static char overviewKey; static const char *myOwnKey = "VideoProperty\0"; static const char intValueKey = 'i'; NSArray *array = [[NSArray alloc] initWithObjects:@ "One", @"Two", @"Three", nil]; // For the purposes of illustration, use initWithFormat: to ensure // we get a deallocatable string NSString *overview = [[NSString alloc] initWithFormat:@"%@", @"First three numbers"]; NSString *videoKeyValue = @"This is a video"; NSNumber *intValue = [[NSNumber alloc]initWithInt:5]; /*Section 1. 关联数据设置部分*/ objc_setAssociatedObject ( array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN ); [overview release]; objc_setAssociatedObject ( array, myOwnKey, videoKeyValue, OBJC_ASSOCIATION_RETAIN ); objc_setAssociatedObject ( array, &intValueKey, intValue, OBJC_ASSOCIATION_RETAIN ); /*Section 3. 关联数据查询部分*/ NSString *associatedObject = (NSString *) objc_getAssociatedObject (array, &overviewKey); NSLog(@"associatedObject: %@", associatedObject); NSString *associatedObject2 = (NSString *) objc_getAssociatedObject(array, myOwnKey); NSLog(@"Video Key value is %@", associatedObject2); NSString *assObject3 = (NSString *) objc_getAssociatedObject(array, &myOwnKey); if( assObject3 ) { NSLog(@"不会进入这里! assObject3 应当为nil!"); } else { NSLog(@"OK. 通过myOwnKey的地址是得不到数据的!"); } NSNumber *assKeyValue = (NSNumber *) objc_getAssociatedObject(array, &intValueKey); NSLog(@"Int value is %d",[assKeyValue intValue]); /*Section 3. 关联数据清理部分*/ objc_setAssociatedObject ( array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN ); objc_setAssociatedObject ( array, myOwnKey, nil, OBJC_ASSOCIATION_ASSIGN ); objc_setAssociatedObject ( array, &intValueKey, nil, OBJC_ASSOCIATION_ASSIGN ); [array release]; } return 0; }
*可以使用如下指令在命令行下编译:
clang -o associates -g -x objective-c++ -Wall associates.mm -framework Foundation -lobjc
一、Display Models: (1) drawing points, (2) drawing lines, and (3) drawing triangles and other polygonal patches.
Drawing points corresponds roughly to the model of a graphics image as a rectangular array of pixels. the model of graphics images as a rectangular array of pixels is only a convenient abstraction and is not entirely accurate. For instance,
on a CRT or television screen, each pixel actually consists of three separate points (or dots of phosphor): each dot corresponds to one of the three primary colors (red, blue, and green) and can be independently set to a brightness value. Thus, each pixel
is actually formed from three colored dots. If the pixels are small enough, they cannot be seen individually by the human viewer, and the image, although composed of points, can appear as a single smooth image. With a magnifying glass, you can see the colors
in the pixel as separate colors (see Figure)
Drawing lines corresponds to vector graphics displays.
Drawing triangles and polygons corresponds to the methods used by modern graphics display hardware for displaying three-dimensional images.
二、shading means varying the color across the triangle.The shading does a fairly good job of masking the polygonal nature of the object and greatly increases the realism of the image.
三、You can change the convention for which face is the front face by using the glFrontFace command.
To make front or back faces invisible, or to do both, you must use the commands glCullFace, glEnable( GL_CULL_FACE );
四、By default, OpenGL draws polygons as solid and filled in. It is possible to change this by using the glPolygonMode function, which determines whether to draw solid polygons, wireframe polygons, or just the vertices of polygons.
五、The term“animation” refers to drawing moving objects or scenes.The movement is only a visual illusion, however; in practice, animation is achieved by drawing a uccession of still scenes, called frames, each showing a static snapshot at an instant in time. The illusion of motion is obtained by rapidly displaying successive frames. This technique is used formovies, television, and computer displays.
六、A region of memory where an image is being created or stored is called a buffer. The image being displayed is stored in the front buffer, and the back buffer holds the next frame as it is being created. Note that swapping buffers does not generally require copying from one buffer to the other; instead, one can just update pointers to switch the identities of the front and back buffers.