2010-01-08 79 views
20

我听说懒惰加载技术相当有助于提高程序的性能。我正在开发iPhone游戏。我不确定如何在客观C中应用延迟加载的方式。有谁能让我看看这个例子吗?懒惰加载的目标C

在此先感谢

+1

延迟加载究竟是什么?你在使用核心数据吗?如果是这样,有关于性能考虑的很好的文档。 – 2010-01-08 07:16:08

回答

28

懒加载一般模式总是或多或少相同:

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

如果你想能够设置它,你可以使用@property和@synthesize?如果是这样,你分配属性的属性(例如,非原子,强等)? – avance 2013-07-02 23:14:01

+1

从最新版本的Xcode开始不再需要'@ synthesize',但是,您可以随时定义'@ property',并在您的类实现中覆盖setter和getter。属性(强,弱等)只能用于反映你自己的实现;编译器会将您的代码替代生成任何代码。希望这可以帮助。 – 2013-07-08 14:55:14

+0

有没有真正简单的库可以帮助您实现这一目标? – fatuhoku 2015-01-23 14:33:02

6

下面是从核心数据模板延迟加载的例子:

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

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

3

在你的* .h类 isDragging_msg和isDecliring_msg这2个是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; 
} 
+0

好方法........ – Wolverine 2013-01-24 07:19:29

3

根据Apple,这将是合适的方式。我同意他们出于多种原因:

  • 一个static方法中的变量将持续多次调用。
  • dispatch_once功能GDC将保证给定的代码块只运行一次。
  • 它是线程安全的。

的Objective-C:

- (AnyClass*)instance { 

    static AnyClass *shared = nil; 
    static dispatch_once_t onceToken; 

    dispatch_once(&onceToken, ^{ 
     shared = [[AnyClass alloc] init]; 
    }); 

    return shared; 
}