2012-08-16 9 views
8

के साथ UIView में प्रवेश करने का उचित तरीका मेरे पास कुछ कस्टम बनाए गए UIViews हैं जो लेआउट के लिए .xib फ़ाइलों का उपयोग करते हैं, और अतिरिक्त सेटअप के लिए बैकिंग क्लासेस का उपयोग करते हैं। मैं इन कक्षाओं को एलोक/इनिट का उपयोग करके और लोडिंग को अपने कस्टम इनिट विधि में नामित करता हूं लेकिन ऐसा करने में स्मृति रिसाव होता है। किसी ने कहा कि alloc भाग वास्तव में एक आत्म उद्देश्य यह है कि इतना लीक किया गया था मैं इस एक के लिए मेरी init विधि समायोजित बनाया:.xib और बैकिंग क्लास

- (id)init 
{ 
    [self autorelease]; 
    self = [[[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject] retain]; 
    [self setupBranding]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)]; 
    [self addGestureRecognizer:tapRecognizer]; 
    [tapRecognizer release]; 

    return self; 
} 

हालांकि, अब जब मैं कोड मैं रिटर्निंग इस चेतावनी मिलती है "का विश्लेषण चलाने 'स्वयं' जबकि यह '[(सुपर या स्वयं) init ...]' के परिणाम के लिए सेट नहीं है। तो मेरा सवाल यह है कि बैकिंग क्लास के साथ कस्टम UIViews करने का सही तरीका क्या है?

चूंकि यह पूछा गया था कि मैं इस तरह इस उपरोक्त कोड का इस्तेमाल किया था:

AssignmentView * assignmentView = [[AssignmentView alloc] init]; 
[self.view addSubview:assignmentView]; 
+2

आम तौर पर, यदि आप किसी xib से कोई दृश्य लोड करते हैं, तो आपको इसे जो भी वर्ग बना रहा है, उसे 'loadNibNamed' के माध्यम से लोड करना चाहिए और फिर इसे' जागृत FromNib' विधि में सेट करना चाहिए, 'init' को स्पर्श भी नहीं करना चाहिए । वैसे भी यह मेरा अनुभव रहा है। क्या आप शायद कुछ कोड जोड़ सकते हैं जहां आप दृश्य को तुरंत चालू कर रहे हैं, और आपकी 'जागृत FromNib' विधि? –

+1

मुझे लगता है कि आप अपनी विधि के शीर्ष पर केवल 'self = [super init]' जोड़ देंगे। पॉल सही है, हालांकि आप आम तौर पर आंतरिक रूप से निब लोडिंग नहीं कर रहे हैं। – Dustin

+0

धन्यवाद, मैं पूरे लोड से बचने की कोशिश कर रहा हूं और इसके बजाय [[MyView alloc] init] का उपयोग करें, लेकिन अगर मुझे इसे फिर से काम करना है और इसके बजाय loadNibNamed का उपयोग करना है तो मुझे लगता है कि मुझे करना है। मेरे पास जागृत नहीं है FromNib विधि लेकिन init में सब कुछ वहाँ जाना होगा। –

उत्तर

17

से दृश्य प्राप्त करें - [NSBundle loadNibNamed:owner:options:], तो इसके फ्रेम अपने दृश्य के सीमा मैच के लिए निर्धारित किया है। आम तौर पर जब आप इसके मूल दृश्य का आकार बदलते हैं तो आप निब आकार में दृश्य भी देखना चाहेंगे।

हम इन परिवर्धन के साथ एक UIView श्रेणी मिल गया है:

- (UIView *)viewFromNib 
{ 
    Class class = [self class]; 
    NSString *nibName = NSStringFromClass(class); 
    NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]; 
    UIView *view = [nibViews objectAtIndex:0]; 
    return view; 
} 


- (void)addSubviewFromNib 
{ 
    UIView *view = [self viewFromNib]; 
    view.frame = self.bounds; 
    [self addSubview:view]; 
} 

तो हमारे -initWithFrame: विधि इस प्रकार है:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self addSubviewFromNib]; 
    } 
    return self; 
} 

बस सुनिश्चित करें कि निब के रूप में एक ही नाम है बनाने काम करने के लिए कक्षा।

+0

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

+0

मुझे पता है कि यह पुराना है, लेकिन यह एक अच्छा समाधान है, और वास्तव में मैं क्या करने की उम्मीद कर रहा था। – Armand

6

क्या आप सुविधा निर्माता शैली का उपयोग करने पर विचार करेंगे?

+ (AssignmentView *)assignmentView 
{ 
    AssignmentView *result = [[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject]; 
    [result setupBranding]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)]; 
    [result addGestureRecognizer:tapRecognizer]; 
    [tapRecognizer release]; 

    return result; 
} 

यह आपको आपके दृश्य को बनाने के दौरान आवश्यक लचीलापन देता है, लेकिन स्मृति रिसाव या चेतावनियां नहीं देता है।

+0

दिलचस्प, मैं इसे एक शॉट दूंगा। –

संबंधित मुद्दे