【问题标题】:Lazy loading in objective C目标 C 中的延迟加载
【发布时间】:2011-01-02 19:39:46
【问题描述】:

我听说延迟加载技术对提高程序的性能很有帮助。我正在为 iPhone 开发游戏。我不确定如何在目标 C 中应用延迟加载。有人可以给我看示例吗?

提前致谢

【问题讨论】:

  • 延迟加载到底是什么?你在使用核心数据吗?如果是这样,则有关于性能注意事项的良好文档。

标签: iphone objective-c


【解决方案1】:

这是一个从 Core Data 模板延迟加载的示例:

- (NSManagedObjectModel *)managedObjectModel
{
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
    return managedObjectModel;
}

第一次请求managedObjectModel,它是由代码创建的。在此之后的任何时候,它都已经存在 (!= nil) 并且刚刚返回。这是延迟加载的一个例子。还有其他类型,例如 NIB 文件的延迟加载(仅在需要时才将它们加载到内存中)。

【讨论】:

    【解决方案2】:

    延迟加载的一般模式总是或多或少相同:

    - (Whatever *)instance
    {
        if (_ivar == nil)
        {
            _ivar = [[Whatever alloc] init];
        }
        return _ivar;
    }
    
    1. 在您的类中,添加您需要的类型的 ivar,并在构造函数中将其初始化为 nil;
    2. 为该 ivar 创建一个 getter 方法;
    3. 在 getter 中,测试 nil。如果是这样,请创建对象。否则,只需返回对它的引用。

    【讨论】:

    • 如果你也想设置它,你可以使用@property 和@synthesize 吗?如果是这样,您分配了哪些属性(例如,非原子、强等)?
    • @synthesize 从 Xcode 的最新版本开始不再需要,但是是的,您始终可以定义 @property 并稍后在您的类实现中覆盖 setter 和 getter。属性(强、弱等)只能用于反映您自己的实现;编译器将您的代码而不是生成任何代码。希望这会有所帮助。
    • 是否有任何非常简单的库可以帮助您实现这一目标?
    【解决方案3】:

    在你的 *.h 类中 isDragging_msg 和 isDecliring_msg 这两个是 BOOL 值。和 Dict_name NSMutableDictionary。

    在视图中确实加载了

    Dict_name = [[NSMutableDictionary alloc] init];
    

    在索引路径处的行的单元格中

    if ([dicImages_msg valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]]) 
    { 
        cell.image_profile.image=[dicImages_msg valueForKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]];
    }
    else
    {
        if (!isDragging_msg && !isDecliring_msg)
        {
            [dicImages_msg setObject:[UIImage imageNamed:@"Placeholder.png"] forKey:[[msg_array objectAtIndex:indexPath.row] valueForKey:@"image name or image link"]];
            [self performSelectorInBackground:@selector(downloadImage_3:) withObject:indexPath];
        }
        else
        {
            cell.image_profile.image=[UIImage imageNamed:@"Placeholder.png"];
        }
    }
    

    下载图片的功能是:-

    -(void)downloadImage_3:(NSIndexPath *)path
    {
        NSAutoreleasePool *pl = [[NSAutoreleasePool alloc] init];
    
        NSString *str=[here Your image link for download];
    
        UIImage *img = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:str]]]; 
    
        [dicImages_msg setObject:img forKey:[[msg_array objectAtIndex:path.row] valueForKey:@"image name or image link same as cell for row"]];
    
        [tableview performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
    
        [pl release];
    }
    

    最后把这些方法放到你的类中

    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        isDragging_msg = FALSE;     
        [tableview reloadData];
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        isDecliring_msg = FALSE;
        [tableview reloadData]; 
    }
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        isDragging_msg = TRUE;
    }
    
    - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
    {
        isDecliring_msg = TRUE; 
    }
    

    【讨论】:

      【解决方案4】:

      这将是根据 Apple 的适当方式。我同意他们的观点有多种原因:

      • 方法中的static 变量将在多次调用中持续存在。
      • GDCdispatch_once 函数将保证给定的代码块只运行一次。
      • 它是线程安全的。

      目标-C:

      - (AnyClass*)instance {
      
          static AnyClass *shared = nil;
          static dispatch_once_t onceToken;
      
          dispatch_once(&onceToken, ^{
              shared = [[AnyClass alloc] init];
          });
      
          return shared;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-06
        • 1970-01-01
        • 2018-05-22
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-02
        相关资源
        最近更新 更多