मैं वर्तमान में आईफोन के लिए एक ऐप बना रहा हूं और यह पता नहीं लगा सकता कि मुझे लीक्स इंस्ट्रूमेंट टूल में मेमोरी लीक क्यों हो रही है।

यहां कोड है और मैंने दो जगहों पर टिप्पणियां जोड़ दी हैं जहां यह हो रहा है।

NSString *pathname = [[NSBundle mainBundle]  pathForResource:self.toUseFile ofType:@"txt" inDirectory:@"/"];
    //Line below causes a leak
    self.rawCrayons = [[NSString stringWithContentsOfFile:pathname encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString:@"\n"];

    self.sectionArray = [NSMutableArray array];
    for (int i = 0; i < 26; i++) [self.sectionArray addObject:[NSMutableArray array]];


    for(int i=0; i<self.rawCrayons.count; i++)
    {
        self.string = [self.rawCrayons objectAtIndex:i];
        NSUInteger firstLetter = [ALPHA rangeOfString:[string substringToIndex:1]].location;
        if (firstLetter != NSNotFound)
        {
            NSInteger audio = AUDIONUM(self.string);
            NSInteger pictures = PICTURESNUM(self.string);
            NSInteger videos = VIDEOSNUM(self.string);
            //Line below causes a leak
            [[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];
        }

        [self.string release];
    }

अग्रिम में धन्यवाद!

संपादित करें

यहाँ मेरी संपत्ति घोषणाएँ हैं।

@property (nonatomic, retain) NSArray *filteredArray;
@property (nonatomic, retain) NSMutableArray *sectionArray;
@property (nonatomic, retain) UISearchBar *searchBar;
@property (nonatomic, retain) UISearchDisplayController *searchDC;
@property (nonatomic, retain) NSString *toUseFile;
@property (nonatomic, retain) NSArray *rawCrayons;
@property (nonatomic, retain) NSString *string;

@property (nonatomic, retain) TermViewController *childController;

यहां लीक हैं जो निक वीवर के सुधारों का पालन करने के बाद हो रहे हैं। मेमोरी लीक्स

एनएससीएफस्ट्रिंग में से एक का विस्तारित संस्करण यहां दिया गया है। मेमोरी लीक इन डेप्थ

और एक और छवि। एक और गहराई में

जिम्मेदार कॉलर वाली छवि: Responsible Caller

इसके अलावा, क्योंकि यह उपयोगी हो सकता है, यहाँ टर्म के लिए गुण हैं:

@property (nonatomic, retain) NSString *name;
@property (nonatomic) NSInteger numberAudio;
@property (nonatomic) NSInteger numberPictures;
@property (nonatomic) NSInteger numberVideos;

और कार्यान्वयन:

@implementation Term

@synthesize name, numberAudio, numberPictures, numberVideos;

- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
    self.name = [toSetName retain];
    self.numberAudio = audio;
    self.numberPictures = pictures;
    self.numberVideos = videos;

    return self;
}

- (NSString*)getName
{
    return [[name retain] autorelease];
}

-(void)dealloc
{
    [name release];
    [super dealloc];
}

@end
1
Flipper 4 अप्रैल 2011, 00:22
1
यह जानना उपयोगी हो सकता है कि rawCrayons संपत्ति को कैसे परिभाषित किया जाता है।
 – 
Jim Blackler
4 अप्रैल 2011, 00:27
ब्लैकलर यह मेरे द्वारा पोस्ट किए गए कोड में है, है ना?
 – 
Flipper
4 अप्रैल 2011, 01:30
मेरा मतलब है हेडर फ़ाइल से परिभाषा, उदा। @property (nonatomic, retain) IBOutlet NSButton *myButton;
 – 
Jim Blackler
4 अप्रैल 2011, 01:38
ब्लैकलर मैंने अपनी संपत्ति की घोषणा ऊपर जोड़ दी है।
 – 
Flipper
4 अप्रैल 2011, 01:59

3 जवाब

सबसे बढ़िया उत्तर

ठीक है, Temp के इस बदले हुए संस्करण को आजमाएं। मैंने गेटटर को हटा दिया है क्योंकि आपके पास पहले से ही संश्लेषित करके एक है। आप नाम के लिए इस तरह गेटर का उपयोग कर सकते हैं:

term.name

समस्या यह थी कि आप नाम कैसे सेट करते हैं: आप नाम की एक प्रति चाहते हैं और इसे बनाए रखने के बिना संश्लेषित सेटर के साथ सेट करना चाहिए। बेशक, आप इसे नाम की प्रतिधारित संपत्ति के साथ सेट कर सकते थे लेकिन आपको इस self.name = toSetName; की तरह बनाए रखना छोड़ देना चाहिए था। सेटर इसे आपके लिए बरकरार रखेगा।

@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger numberAudio;
@property (nonatomic) NSInteger numberPictures;
@property (nonatomic) NSInteger numberVideos;


@implementation Term

@synthesize name, numberAudio, numberPictures, numberVideos;

- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
    self.name = toSetName;
    self.numberAudio = audio;
    self.numberPictures = pictures;
    self.numberVideos = videos;

    return self;
}

-(void)dealloc
{
    [name release];
    [super dealloc];
}

किसी ऑब्जेक्ट को किसी सरणी में जोड़ने से इंस्टेंस बरकरार रहेगा, इसलिए रिटेन 2 है क्योंकि आप कॉल करते हैं

[[टर्म आवंटन] initToCall..

कुछ ऐसा करें

Term *term = [[Term alloc] initToCall..];

[theArray addObject:term];

[term release];

<मजबूत>1. पता कॉलम में पहली पंक्ति में तीर देखें? इसे क्लिक करें! यहां छवि विवरण दर्ज करें

<मजबूत>2. क्लिक करने के बाद :) यहां छवि विवरण दर्ज करें

2
Nick Weaver 5 अप्रैल 2011, 18:27
वीवर मैंने इसका अनुसरण किया और अब मुझे एनएससीएफस्ट्रिंग में एक रिसाव मिल रहा है, जब मैं इसे डबल क्लिक करता हूं, तो यह सिर्फ असेंबली कोड होता है।
 – 
Flipper
4 अप्रैल 2011, 01:36
1
सबसे पहले, अपने एनएसएसटींग गुणों को बनाए रखने से प्रतिलिपि में बदलें: एनएसएसटींग अपरिवर्तनीय हैं इसलिए आप इसकी एक प्रति चाहते हैं जो कुछ प्रक्रिया द्वारा पृष्ठभूमि में बदल सकती है।
 – 
Nick Weaver
4 अप्रैल 2011, 11:31
1
मेरी राय है: हाँ, मैं इसे इस तरह से करता हूँ। यदि आप पूरी पुस्तकों को स्ट्रिंग्स में संग्रहीत नहीं करते हैं, तो कॉपी NSStrings के लिए सही विकल्प है। NSString प्रॉपर्टी कॉपी या रिटेन पर एक नज़र डालें, यह अंतर को बहुत अच्छी तरह से समझा रहा है।
 – 
Nick Weaver
4 अप्रैल 2011, 18:25
1
मैं नहीं बता सकता, आपको पता लगाना होगा। यहां समस्या हल करना पुनरावृत्त है, मेरे पास रनिंग कोड नहीं है, इसलिए मैं केवल दी गई जानकारी के आधार पर अगले चरण में मदद कर सकता हूं।
 – 
Nick Weaver
4 अप्रैल 2011, 18:50
1
नए कोड के लिए धन्यवाद, मुझे लगता है कि हम एक समाधान के करीब हैं। मेरा उत्तर अद्यतन देखें।
 – 
Nick Weaver
5 अप्रैल 2011, 19:44

आपको यह बताना मुश्किल है कि पहला क्यों लीक हो रहा है, क्योंकि हम नहीं जानते कि संपत्ति को क्या घोषित किया गया है। बरकरार है? नकल? असाइन करें? क्या?

आखिरी वाला काफी आत्म व्याख्यात्मक है, हालांकि, आप टर्म ऑब्जेक्ट का स्वामित्व ले रहे हैं, और इसे जोड़े जाने पर इसे जारी नहीं कर रहे हैं। addObject: अपने तर्क को बरकरार रखता है, जिसका अर्थ है कि यदि आपको अब उस शब्द की आवश्यकता नहीं है, तो आपको स्वामित्व छोड़ना होगा। यानी, अपने initToCall:::: के परिणाम के लिए -autorelease पास करें (जो बीटीडब्ल्यू एक विधि के लिए एक बहुत बुरा नाम है)

1
jer 4 अप्रैल 2011, 00:35

परिवर्तन:

[[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];

प्रति:

Term *tempTerm = [[Term alloc] initToCall:NAME(self.string):audio:pictures:videos];
[[self.sectionArray objectAtIndex:firstLetter] addObject:tempTerm];
[tempTerm release];

किसी वस्तु को आवंटित करके आप इसके रिलीज के लिए जिम्मेदार हैं।

1
Joe 4 अप्रैल 2011, 00:36