Я новичок в iOS c, и теперь я создаю приложение, которое работает с FtpServer, чтобы получить список папок и поместить в UiTableView.
С этим кодом я работаю с потоком:
-(void) readStream {
CFURLRef ftpURL=(CFURLRef)url;
CFReadStreamRef readFTPStream=CFReadStreamCreateWithFTPURL(kCFAllocatorDefault, ftpURL);
CFReadStreamSetProperty(readFTPStream,kCFStreamPropertyFTPUserName,userName);
CFReadStreamSetProperty(readFTPStream,kCFStreamPropertyFTPPassword,password);
CFReadStreamSetProperty (readFTPStream,kCFStreamPropertyFTPUsePassiveMode,NO);
MyStreamInfo streamInformation;
streamInformation.readStream=readFTPStream;
CFStreamClientContext clientContext={0,self,NULL,NULL,NULL};
CFOptionFlags events= kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered;
BOOL flagOpen=CFReadStreamSetClient(readFTPStream, events,(void*)didStartReceiveList, &clientContext);
if (flagOpen) {
CFReadStreamScheduleWithRunLoop(readFTPStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
//CFReadStreamUnscheduleFromRunLoop(readFTPStream, CFRunLoopGetCurrent(), kCFRunLoopRunFinished);
}
if(!CFReadStreamOpen(readFTPStream)){
NSLog(@"Could not open read stream");
}
NSLog(@"fine");
}
Итак, я callbackFunction для получения события:
void didStartReceiveList(NSInputStream *stream,CFStreamEventTypeevent,CFStreamClientContext *clientContext) {
//ViewController *self = (__bridge_transfer ViewController *)clientContext;
ViewController *self=( ViewController *)clientContext;
switch(event) {
case kCFStreamEventHasBytesAvailable:{
[self readStreamData:(CFReadStreamRef)stream :clientContext];
}
break;
case kCFStreamEventErrorOccurred: {
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"iFTP"
message:[self message]
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
break;
case kCFStreamEventEndEncountered:{
//reload data
**here in the reload i receive Signal crash**
[self.tb reloadData];
}
break;
}
}
и это потоковый метод
-(void) readStreamData:(CFReadStreamRef) stream :(CFStreamClientContext*) context {
MyStreamInfo *info=context->info;
int offset=0;
CFIndex bytesRead = CFReadStreamRead(stream, info->buffer + offset,kMyBufferSize-offset);
if (bytesRead < 0) {
CFErrorRef err=CFReadStreamCopyError(stream);
CFStringRef str=CFErrorCopyDescription(err);
NSString *descr=(__bridge_transfer NSString *)str;
self.message=[NSString stringWithString:descr];
fprintf(stderr, "CFReadStreamRead returned %ld: %s.", bytesRead,strerror(errno));
CFRelease(err);
} else if (bytesRead == 0) {
self.message=[[NSString alloc ]initWithString:@"Nothing to read"];
fprintf(stderr, "CFReadStreamRead returned %ld: %s.", bytesRead,strerror(errno));
//CFReadStreamClose(stream);
}
int bufSize = bytesRead + offset;
int totalBytesRead=0;
totalBytesRead+= bufSize;
int totalBytesConsumed=0;
CFIndex bytesReturned;
const UInt8 *newBuffer=info->buffer+totalBytesConsumed;
NSDictionary *d=[[NSDictionary alloc]init];
if (bytesRead>0) {
do {
const UInt8 *buffRemaining=info->buffer+totalBytesConsumed;
NSDictionary *dict=[[NSDictionary alloc] init];
CFDictionaryRef dictionaryParsed=(__bridge_retained CFDictionaryRef)dict;
bytesReturned=CFFTPCreateParsedResourceListing(NULL, newBuffer, bufSize, &dictionaryParsed);
if (bytesReturned>0) {
if (dictionaryParsed!=NULL) {
d=(__bridge_transfer NSDictionary *)dictionaryParsed;
NSString *name=[d valueForKey:(NSString *)kCFFTPResourceName];
[self.listEntries addObject:name];
}
totalBytesConsumed += bytesReturned;
bufSize -= bytesReturned;
info->leftOverByteCount = bufSize;
; newBuffer=info->buffer+totalBytesConsumed;
}
else if (bytesReturned == 0) {
info->leftOverByteCount = bufSize;
totalBytesRead -= info->leftOverByteCount;
memmove(info->buffer, buffRemaining, info->leftOverByteCount);
}
else if (bytesReturned == -1) {
alert=[[UIAlertView alloc] initWithTitle:@"iFTP"
message:@"CFFTPCreateParsedResourceListing parse failure"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
break;
}
} while (bytesReturned>0 );
//self.tb.delegate=self;
//Add new records to the table
//ViewController *self = (ViewController *)context;
//[self.tb beginUpdates];
NSMutableArray *iPath=[[NSMutableArray alloc] init];
for (int i=0; i<[listEntries count]; i++) {
NSIndexPath *iP=[NSIndexPath indexPathForRow:i inSection:0];
[iPath addObject:iP];
}
}
}
Код работает нормально, за исключением того, что при обратном вызове didreceiveStart в конце события я решаю перезагрузить данные моего табличного представления.
Я не знаю, почему я не могу использовать в этой точке данные перезагрузки self.tableview
Кто-нибудь может мне помочь?
Спасибо в
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tb dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
@try {
cell.textLabel.text=[listEntries objectAtIndex:indexPath.row];
}
@catch (NSException *exception) {
NSLog(@"%@",exception.reason);
}
@finally {
NSLog(@"%@",cell.textLabel.text);
}
cell.textLabel.textColor=[UIColor blackColor];
CGFloat r=255;
CGFloat g=140;
CGFloat b=0;
cell.backgroundColor=[UIColor colorWithRed:r green:g blue:b alpha:1.0];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(@"%d",[listEntries count]);
return [listEntries count];
}