第一个工程编译成功
代码如下:
//
// main.m
// App02
//
// Created by Cocoa on 7/1/17.
// Copyright © 2017 zsy. All rights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 创建一个文件写入流
char * filePath = "file:///Users/cocoa/Desktop/timezones";
CFStringRef fileStr = CFStringCreateWithCString(kCFAllocatorDefault, filePath, kCFStringEncodingUTF8);
CFURLRef fileUrl = CFURLCreateWithString(kCFAllocatorDefault, fileStr, NULL);
CFWriteStreamRef myWriteStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, fileUrl);
if (!CFWriteStreamOpen(myWriteStream)) { // 打开流对象失败
// 获取错误
CFStreamError myerr = CFWriteStreamGetError(myWriteStream);
if (myerr.domain == kCFStreamErrorDomainPOSIX) {
} else if (myerr.domain == kCFStreamErrorDomainMacOSStatus) {
OSStatus macError = (OSStatus)myerr.error;
}
}
UInt8 buf[] = "Hello world";
CFIndex buflen = (CFIndex)strlen(buf);
BOOL done = FALSE;
while (!done) {
CFIndex bytesWritten = CFWriteStreamWrite(myWriteStream, buf, buflen);
if (bytesWritten < 0) { // 写入错误
CFStreamError err = CFWriteStreamGetError(myWriteStream);
// 报告错误
NSLog(@"数据写入错误.");
} else if (bytesWritten == 0) {
if (CFWriteStreamGetStatus(myWriteStream) == kCFStreamStatusAtEnd) { // 数据写入完成
done = TRUE;
}
} else if (bytesWritten != buflen) { // 数据还没有写完
buflen = buflen - bytesWritten;
memmove(buf, buf + bytesWritten, buflen);
// 分析写入流哪里出错了
CFStreamError err = CFWriteStreamGetError(myWriteStream);
// 处理错误 err
continue;
}
done = TRUE;
}
// 关闭和销毁流读取对象
CFWriteStreamClose(myWriteStream);
CFRelease(fileUrl);
CFRelease(fileStr);
myWriteStream = NULL;
fileUrl = NULL;
fileStr = NULL;
}
return 0;
}
第二个工程编译失败,
代码如下:
//
// main.m
// App03
//
// Created by Cocoa on 7/1/17.
// Copyright © 2017 zsy. All rights reserved.
//
#import <Foundation/Foundation.h>
void myRetaion(char * ptr);
void myRelease(char * ptr);
void myCopyDesc(char * ptr);
// 回调函数
void myCallBack(CFReadStreamRef stream,CFStreamEventType event,void * myPtr);
int main(int argc, const char * argv[]) {
@autoreleasepool {
char * hostStr = "127.0.0.1"; // 这里是一个远程的主机
UInt32 port = 18888;
CFStringRef hostString = CFStringCreateWithCString(kCFAllocatorDefault, hostStr, kCFStringEncodingUTF8);
// 创建 ReadStream 对象
CFReadStreamRef myReadStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, hostString, port, &myReadStream, NULL);
// 在打开 Socket Read Stream 之前 创建一个 Context
char * myPtr = "";
CFStreamClientContext myContext = {0,myPtr,myRetaion,myRelease,myCopyDesc};
// 打开流之前将流添加 RunLoop 中
CFOptionFlags registeredFlags = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
if (CFReadStreamSetClient(myReadStream, registeredFlags, myCallBack, &myContext)) {
// 设置流成功
// 将流添加到 RunLoop 中
CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}
// 打开一个非阻塞的读取流
if (!CFReadStreamOpen(myReadStream)) {
// 如果打开失败
CFStreamError myErr = CFReadStreamGetError(myReadStream);
if (myErr.error != 0) {
// 一个错误发生了
if (myErr.domain == kCFStreamErrorDomainPOSIX) {
} else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) {
OSStatus macError = (OSStatus)myErr.error;
}
}
} else {
CFRunLoopRun();
}
}
return 0;
}
void myRetaion(char * ptr) {
}
void myRelease(char * ptr) {
}
void myCopyDesc(char * ptr) {
}
// 回调函数
void myCallBack(CFReadStreamRef stream,CFStreamEventType event,void * myPtr) {
switch (event) {
case kCFStreamEventHasBytesAvailable:
// It is safe to call CFReadStreamRead,it won't block because bytes are avaliable.
UInt8 buf[BUFSIZ];
CFIndex bytesRead = CFReadStreamRead(stream, buf, BUFSIZ);
if (bytesRead > 0) {
// 读取到数据了
NSLog(@"%S",buf);
}
// bytesRead == 0 和 bytesRead < 0 的情况可以忽视因为这些情况会触发其他事件
break;
case kCFStreamEventErrorOccurred:
CFStreamError error = CFReadStreamGetError(stream);
// 报告错误
// reportError(error);
// 关闭和释放流
CFReadStreamClose(stream);
CFRelease(stream);
break;
case kCFStreamEventEndEncountered:
// 所有的数据都已经读取完毕了
// reportCompletion();
// 将流冲 RunLoop 中移除,并且关闭和销毁流
CFReadStreamUnscheduleFromRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFReadStreamClose(stream);
CFRelease(stream);
break;
default:
break;
}
}
错误报告:
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:30:13: error: expected expression
UInt8 buf[BUFSIZ];
^
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:31:58: error: use of undeclared identifier 'buf'
CFIndex bytesRead = CFReadStreamRead(stream, buf, BUFSIZ);
^
warning: format specifies type 'const unichar *' (aka 'const unsigned short *') but the argument has type '<dependent type>' [-Wformat]
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:34:29: error: use of undeclared identifier 'buf'
NSLog(@"%S",buf);
^
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:41:13: error: expected expression
CFStreamError error = CFReadStreamGetError(stream);
^
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:81:52: warning: incompatible pointer types initializing 'void *(*)(void *)' with an expression of type 'void (char *)' [-Wincompatible-pointer-types]
CFStreamClientContext myContext = {0,myPtr,myRetaion,myRelease,myCopyDesc};
^~~~~~~~~
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:81:62: warning: incompatible pointer types initializing 'void (*)(void *)' with an expression of type 'void (char *)' [-Wincompatible-pointer-types]
CFStreamClientContext myContext = {0,myPtr,myRetaion,myRelease,myCopyDesc};
^~~~~~~~~
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:81:72: warning: incompatible pointer types initializing 'CFStringRef (*)(void *)' with an expression of type 'void (char *)' [-Wincompatible-pointer-types]
CFStreamClientContext myContext = {0,myPtr,myRetaion,myRelease,myCopyDesc};
^~~~~~~~~~
/Users/cocoa/Documents/Xcode/Objective-C/Workspace02/App03/App03/main.m:105:30: warning: unused variable 'macError' [-Wunused-variable]
OSStatus macError = (OSStatus)myErr.error;
^
5 warnings and 4 errors generated.
简单的说,错误是这个样子的:
错误解决方法:
case 里面有局部变量需要用大括号括起来