Я пытаюсь отправить файлы по Bluetooth-соединению.
Я получил это на работу благодаря моему предыдущему посту , но этот метод не был эффективным с точки зрения памяти.
Весь файл был загружен в память перед отправкой, и это создало проблемы (и привело к сбою приложения) для файлов размером> ~ 20 МБ.Поэтому я предложил новый метод чтения только тех частей файла, которые мне нужны в определенное время, создания пакетов из данных, их отправки и повторения процесса для каждого фрагмента файла размером 8 КБ.
Поэтому я создал метод класса, который генерирует пакет, сообщает контроллеру, что пакет доступен (через протокол), и повторяет этот процесс для каждого доступного пакета.
Вот код для генератора пакетов:
+ (void)makePacketsFromFile:(NSString *)path withDelegate:(id <filePacketDelegate>)aDelegate {
if (![[NSFileManager defaultManager] fileExistsAtPath:path] || aDelegate == nil) return;
id <filePacketDelegate> delegate;
delegate = aDelegate;
const NSUInteger quanta = 8192;
uint filesize;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
filesize = [[fileAttributes objectForKey:NSFileSize] intValue];
int numOfPackets = (int)ceil(filesize/quanta);
if (numOfPackets == 0) numOfPackets = 1;
NSLog(@"filesize = %d, numOfPackets = %d or %.3f", filesize, numOfPackets, (float)ceil(filesize/quanta));
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
int offset = 0;
int counter = 0;
while (counter != (numOfPackets + 1)) {
uint len = (filesize < quanta) ? filesize : quanta;
if (counter == numOfPackets) {
len = filesize - offset;
}
[handle seekToFileOffset:offset];
NSData *fileData = [handle readDataOfLength:len];
file_packet *packet = [[file_packet alloc] initWithFileName:[path lastPathComponent] ofType:0 index:counter];
packet.packetContents = fileData;
[fileData release];
packet.checksum = @"<to be done>";
packet.numberOfPackets = [NSString stringWithFormat:@"%d", numOfPackets];
[delegate packetIsReadyForSending:packet];
[packet release];
offset += quanta;
counter++;
}
[handle closeFile];
}
И получение и отправка файла:
- (void)packetIsReadyForSending:(file_packet *)packet {
NSData *fileData = [packet dataForSending];
[self.connectionSession sendDataToAllPeers:fileData withDataMode:GKSendDataReliable error:nil];
}
- (void)sendFileViaBluetooth {
[file_packet makePacketsFromFile:selectedFilePath withDelegate:self];
}
Однако использование памяти довольно велико.Не то, что я ожидал.
Я немного застрял в этом, поскольку не хотел бы ограничивать общий доступ по Bluetooth для файлов размером менее 20 МБ.
Любая помощь приветствуется.
Изменить: Я думал об этом некоторое время и пришел к выводу, что не мой код вызывает проблему с выделением памяти, а стек GameKit для отправки пакетов.
Я думаю, что генерирую слишком многопакеты слишком быстрые, и я не думаю, что GameKit отправляет их достаточно быстро.
Поэтому я сейчас думаю о том, как узнать, когда GameKit отправил пакет, и сгенерировать еще один, когда GameKit подтвердит, что этоотправлено.