0

Я разработал проект, в котором пользователь рисует изображение на холсте, я храню его в файле с помощью CoreData, у меня есть отношения «один ко многим», называемые папками. Итак, вот все изображения. Я извлекаю изображения из файлов, изменяю размер в соответствии с высотой ячейки таблицы и показываю ее на таблице. Как только он будет показан, я хочу кэшировать изображения.Как использовать NSCache с CoreData

У меня также есть несколько ярлыков в ячейке папки, которые дают мне некоторую информацию о моих файлах, которую я обновляю на лету. Я также провёл клетки, чтобы отметить ее, и переместил ее в нижнюю часть ячейки.

Я также показываю одинаковые изображения файлов в разных представлениях в зависимости от того, как пользователь запрашивает его.

Я хочу знать лучший способ для этого, я читаю через Интернет, их много методов, GCD, NSOperationQueues и многие другие.

Какой метод лучше всего подходит для меня.

Я хочу показать некоторый код

- (UITableViewCell *)tableView:(FMMoveTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    FolderCell *tableCell = (FolderCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (tableCell == nil) 
    { 
     NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FolderCell" owner:self options:nil]; 
     tableCell = [nib objectAtIndex:0]; 
    } 

    NSMutableArray *categoryArray = [[self.controller fetchedObjects]mutableCopy]; 

    Folder *category = [categoryArray objectAtIndex:[indexPath row]]; 

    [tableCell configureCellWithNote:category]; //This function is written in my FolderCell.m function   

} 
    return tableCell; 
} 


-(void)configureCellWithNote:(Folder *)category 
{  
    self.category = category; 


    UIImage *image1 = [UIImage imageWithData:category.noteImage]; 
    CGSize newSize; 


    if(image1.size.width == 620 && image1.size.height == 200) 
    {    
     newSize = CGSizeMake(300, 97); 
    }  

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); 

    [image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 


    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext();  

    self.notesImage.image = newImage;  
} 

Так что же происходит в том, что configureCellWithNote занимает много времени, потому что это изменение размеров изображений. Пожалуйста, помогите мне решить, как эта проблема может быть решена.

С уважением Rajit

+0

Я думаю ipmcc ответил на вопрос тайника. Кстати, я мог бы склонить эту логику изменения размера изображения к категории «UIImage». Кроме того, что, если изображение не было 620x200, тогда это не сработает должным образом. Безопаснее использовать общий алгоритм изменения размера, для которого вы можете использовать 'UIViewContentModeScaleAspectFill' или' UIViewContentModeScaleAspectFit', например. http://stackoverflow.com/questions/10491080/uiimage-resizing-not-working-properly/10491692#10491692 – Rob

ответ

1

Если вы просто хотите, чтобы перетасовать операцию изменения размера в фоновом потоке, вы могли бы сделать что-то вроде этого:

- (void)configureCellWithNote:(Folder *)category 
{ 
    self.category = category; 

    UIImage *image1 = [UIImage imageWithData:category.noteImage]; 
    CGSize newSize; 

    if(image1.size.width == 620 && image1.size.height == 200) 
    { 
     newSize = CGSizeMake(300, 97); 
    } 

    dispatch_async(dispatch_get_global_queue(0,0), ^{ 
     UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); 

     [image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; 

     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

     UIGraphicsEndImageContext(); 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      self.notesImage.image = newImage; 
     }); 
    }); 

} 

Если вы хотите кэшировать результаты, то трюк будет придумать хороший ключ кеша. К сожалению, трудно сказать, из чего вы опубликовали то, что сделало бы хороший ключ кэш. Конечно, он должен будет включать размер, но он также должен будет включить что-то, что связывает его с категорией. Я полагаю, что если вы не можете использовать NSManagedObjectID для категории, но я думаю, что это будет специфично для каждого контекста управляемого объекта. Если предположить, что была собственность на Folder называется uniqueName реализация кэширования может выглядеть следующим образом:

- (UIImage*)imageForCategory: (Folder*)category atSize: (CGSize)size 
{ 
    // A shared (i.e. global, but scoped to this function) cache 
    static NSCache* imageCache = nil; 
    // The following initializes the cache once, and only once 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     imageCache = [[NSCache alloc] init]; 
    }); 

    // Generate a cache key sufficient to uniquely identify the image we're looking for 
    NSString* cacheKey = [NSString stringWithFormat: @"%@|%@", category.uniqueName, NSStringFromSize((NSSize)size)]; 
    // Try fetching any existing image for that key from the cache. 
    UIImage* img = [imageCache objectForKey: cacheKey]; 

    // If we don't find a pre-existing one, create one 
    if (!img) 
    { 
     // Your original code for creating a resized image... 
     UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); 
     UIImage* image1 = [UIImage imageWithData:category.noteImage]; 
     [image1 drawInRect:CGRectMake(0,0,size.width,size.height)]; 
     img = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     // Now add the newly-created image to the cache 
     [imageCache setObject: img forKey: cacheKey]; 
    } 

    // Return the image 
    return img; 
} 
+0

Привет, @ipmcc, спасибо за ваш ответ, у меня есть атрибут, называемый именем папки. Таким образом, код, который вы показали, должен я написать его в tableCell.m или в моей функции ViewController.m «CellForRowAtIndexPath». И только этот код будет обрабатывать кеширование изображений? Извините, что спросила об этом, но я новичок в этом. Не могли бы вы объяснить код, который вы написали. – Ranjit

+0

Вероятно, это имеет смысл в классе ViewController, а не в классе TableCell. Этот код должен обрабатывать кеширование изображений. Если кэш не содержит изображения для определенной папки и размера, он будет генерировать его. – ipmcc

+0

+1 На отличном ответе. Кстати, учитывая, что «NSCache» изменил свое поведение, действующее на iOS 7, вам может потребоваться подкласс «NSCache», чтобы вы реагировали на давление памяти. См. Http://stackoverflow.com/questions/19546054/nscache-crashing-when-memory-limit-is-reached-only-on-ios-7.Что касается кэширования в контроллере или классе ячеек, если есть вероятность, что вам могут понадобиться эти измененные изображения в другом месте, вы, вероятно, не хотите этого в любом из этих классов, а скорее в каком-то контроллере модели или синглете, который делает его доступным для других просматривать контроллеры. – Rob

Смежные вопросы