2009-02-20 24 views
7

कॉपी करना मैं एक निब फ़ाइल से tableView:cellForRowAtIndexPath: में एक कस्टम टेबल सेल पढ़ रहा हूं। यह मेरे उद्देश्यों के लिए बहुत अच्छा काम करता है, सिवाय इसके कि यह काफी धीमा है।UITableViewCell

अब, मुझे पता है कि लंबी अवधि में करने के लिए सही बात यह है कि सेल को पूरी तरह से कोड में बनाना है, और एक दृश्य का उपयोग करना है, और इसी तरह। लेकिन यह एक प्रोटोटाइप है, और मैं इसमें इतना प्रयास नहीं करना चाहता हूं।

अभी के लिए, अगर मैं UIViewController सबक्लास में केवल एक बार निब पढ़ रहा था, तो मुझे खुशी होगी, तो tableView:cellForRowAtIndexPath: इसकी प्रतियां बनाये गये हैं। मेरी धारणा यह है कि प्रतिलिपि निब पढ़ने से तेज होगी।

यहाँ है कि मैं क्या निब, जो मैं (के बाद और retain) viewDidLoad: से फोन

-(id)loadFromNamed:(NSString*)name { 
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name 
                  owner:self 
                 options:nil]; 
    assert(objectsInNib.count == 1); 
    return [objectsInNib objectAtIndex:0]; 
} 

सभी अब तक अच्छा है लोड करने के लिए उपयोग करते हैं। लेकिन सवाल यह है कि: मैं इसे और अधिक कैसे कॉपी करूं? क्या यह भी संभव है?

मैंने [_cachedObject copy] और [_cachedObject mutableCopy] की कोशिश की लेकिन UITableViewCell या तो प्रतिलिपि प्रोटोकॉल का समर्थन नहीं करता है।

यदि मुझे करना है, तो मैं उन्हें गति को अनदेखा करने के लिए कह सकता हूं जब तक कि मैं पूरी तरह से निब को हटाने के लिए तैयार नहीं हूं, लेकिन अगर यहां कम लटकते फल हैं तो मैं इसे थोड़ा तेज कर दूंगा।

कोई विचार?

उत्तर

6

तालिका दृश्य में बनाए गए सेल क्लोनिंग का उपयोग करें। ऐप्पल जानता था कि बहुत सारी टेबल कोशिकाएं धीमी थीं। इस विधि के लिए डॉक्स की जाँच करें:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier 

आप सेल एक बार बनाने के लिए, तो के रूप में नई कोशिकाओं अनुरोध कर रहे हैं, मौजूदा कोशिकाओं क्लोन करने के लिए है कि विधि का उपयोग करें। फिर आप नए सेल के बारे में क्या बदलना चाहते हैं और सेल ऑब्जेक्ट को वापस लेना चाहते हैं।

ऐप्पल द्वारा प्रदान किए गए तालिका दृश्य वास्तविक नमूना कोड को भी देखें जो इस विधि का उपयोग करता है और आपको सही तरीका दिखाता है। तथ्य यह है कि आपका सेल निब से लोड किया गया था, इससे कोई फर्क नहीं पड़ता।


मामूली स्पष्टीकरण: मैं आपके लिए उपर्युक्त विधि क्लोन कोशिकाओं को नहीं सोचता। इसके बजाए यह सेल ऑब्जेक्ट लेता है जिसने स्क्रीन को स्क्रॉल किया है और उन्हें आसानी से एक नए स्थान पर ले जाता है। तो यह सचमुच एक सेल का पुन: उपयोग कर रहा है। तो सुनिश्चित करें कि आपका कस्टम टेबल दृश्य इंटिलाइजेशन के बाहर की सभी नए मानों पर सेट किया जा सकता है।

+0

धन्यवाद। मैं 'dequeueReusableCellWithIdentifier' के बारे में भूल गया था। अब मैं इसका उपयोग कर रहा हूं, लेकिन यह अभी भी धीमा है जितना मैं चाहता हूं। इससे पता चलता है कि बाधा ड्राइंग में है, जिसे तब तक इंतजार करना पड़ेगा जब तक कि मेरे पास अन्य फास्ट टेबल चाल लागू करने का समय न हो। लेकिन अब मुझे पता है कि क्या हो रहा है! –

+0

वैसे आपका दृष्टिकोण भी धीमा हो गया होगा क्योंकि ऑब्जेक्ट्स का पुन: उपयोग करना ऑब्जेक्ट क्लोनिंग से कहीं अधिक तेज़ है। मैं खुशी से मदद कर सकता है। –

+0

धीमे चलने वाले कुछ निश्चित रूप से देखने के लिए डिवाइस पर प्रोफाइलिंग करने का प्रयास करें। कुछ लोग कहते हैं कि यह चाल प्रति सेल केवल एक दृश्य का उपयोग करना है और अपनी सभी ड्राइंग करना है। –

3

अच्छा, मुझे यकीन नहीं है कि वहां सभी ट्यूटोरियल इस चरण को निर्दिष्ट क्यों नहीं करते हैं।

निब से अपने स्वयं के कस्टम UITableViewCell का उपयोग करते समय, dequeueReusableCellWithIdentifier को कॉल करना पर्याप्त नहीं है। आपको आईबी में "पहचानकर्ता" निर्दिष्ट करना होगा, केवल इसके लिए तालिका दृश्य सेल टैब अनुभाग में।

फिर सुनिश्चित करें कि आईबी में जो पहचानकर्ता आपने डाला है वह पहचानकर्ता के समान है जो आप dequeueReusableCellWithIdentifier के लिए उपयोग करते हैं।

4

इस समाधान पर गर्व नहीं है, लेकिन यह संभव आईबी बाइंडिंग की अधिकतम संख्या के साथ काम करता है:

इंटरफेस (AlbumTableViewCell जो का एक उदाहरण AlbumViewController के XIB फ़ाइल में परिभाषित किया गया है UITableViewCell का एक उपवर्ग है):

@interface AlbumsViewController : UITableViewController { 
    IBOutlet AlbumTableViewCell *tableViewCellTrack; 
} 

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack; 

कार्यान्वयन (असंग्रहित/संग्रह एक कॉपी/क्लोन तालिका दृश्य सेल बना देता है):

@implementation AlbumsViewController 

@synthesize tableViewCellTrack; 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"]; 

    if (cell == nil) { 
     AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease]; 
     [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil]; 

     cell = albumsViewController.tableViewCellTrack; 
    } 

    cell.labelTitle.text = ...; 
    cell.labelArtist.text = ...; 

    return cell; 
} 
8

मैं मेज सेल के मुकाबला लगता है एल को डीक्यूइंग तंत्र के साथ एक साथ इस्तेमाल किया जा सकता है, जो सेल को एक बार बनाने की अनुमति देगा (निब या प्रोग्रामेटिक रूप से या इसे अन्य निब से स्वचालित रूप से लोड किया जा रहा है और आईबी में आउटलेट के रूप में लिंक किया जा रहा है) और उसके बाद इसे क्लोन करें या आवश्यकता होने पर इसे हटा दें।

UITableViewCell एनएससीपीआईपी प्रोटोकॉल के अनुरूप नहीं है, लेकिन यह कुंजी संग्रह/अनारक्षित तंत्र का समर्थन करता है, इसलिए इसका उपयोग क्लोनिंग के लिए किया जा सकता है।

जवाब के आधार पर " How to duplicate a UIButton in Objective C?" मेरे डेटा स्रोत प्रतिनिधि विधि लगता है: self.tableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellID = @"CellIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID]; 

    if (!cell) { 
     NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell]; 
     cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData]; 
    } 

    // ... config ... 

    return cell; 
} 

और मेरे मामले में एक सेल दृश्य के निब फ़ाइल से एक बार लोड किया गया था है।

मैं परीक्षण नहीं क्या हो जाएगा तेजी से: "संग्रह + असंग्रहित" "लोड निब फ़ाइल + असंग्रहित" जो ढांचे के -loadNibNamed मामले में क्या होगा क्लोन या करने के लिए: मालिक: विकल्प:, मैं इस विधि का इस्तेमाल किया केवल सुविधा विचारों के साथ, लेकिन अच्छी संभावना है कि मेमोरी ऑपरेशन बनाम फ़ाइल ऑपरेशन तेजी से होगा।

संपादित करें: ऐसा लगता है कि यह पहले जैसा प्रतीत नहीं होता था। चूंकि UIImage एनएससीओडी के अनुरूप नहीं है, कॉन्फ़िगर किए गए UIImageViews वाले कक्षों को अतिरिक्त कोड के बिना कॉपी नहीं किया जा सकता है। हां, पूरी छवि की प्रतिलिपि निश्चित रूप से एक अच्छा अभ्यास नहीं है, यह इंगित करने के लिए ऐप्पल को जयकार।

+0

वाह मैंने इस पोस्ट के लिए नहीं होने पर UITableViewCell को डुप्लिकेट करने का तरीका कभी नहीं सोचा होगा। बहुत धन्यवाद। –

+0

बाधाओं को संग्रह/अनारक्षित के माध्यम से नहीं बनाया गया :-( –

1

यहाँ यह स्विफ्ट

में है
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    var cell : UITableViewCell? 
    let cellId = String(format: "Cell%d", indexPath.row) 
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell? 

    if cell == nil { 
     let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!) 
     cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell? 
    } 

    // do some stuff 

    return cell! 
}