2010-01-08 80 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; 
}