类工作不正确。如何使它更好? [英] Class works not correct. How to make it better?

查看:120
本文介绍了类工作不正确。如何使它更好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写过类,并希望向你展示...



我认为这个类写得不正确,这就是为什么我在我的应用程序中有韭菜。首先 delloc 从不调用。



$ b

Articles.h

$ b

  #import< Foundation / Foundation.h> 

@interface文章:NSObject {
BOOL favorite;
NSMutableString * title;
NSMutableString * summary;
NSMutableString * mainLink;
NSMutableString * pubDate;
NSMutableString * author;
NSMutableString * imageLink;
}

@property(nonatomic,assign)BOOL favorite;
@property(nonatomic,retain)NSMutableString * title;
@property(nonatomic,retain)NSMutableString * summary;
@property(nonatomic,retain)NSMutableString * mainLink;
@property(nonatomic,retain)NSMutableString * pubDate;
@property(nonatomic,retain)NSMutableString * author;
@property(nonatomic,retain)NSMutableString * imageLink; (NSString *)inMainLink summary:(NSString *)inSummary
pubDate:(NSString *)inPubDate作者:(NSString *) inAuthor imageLink:(NSString *)inImageLink;


//设置方法
- (void)setTheTitle:(NSString *)inTitle;
- (void)setTheMainLink:(NSString *)inMainLink;
- (void)setTheSummary:(NSString *)inSummary;
- (void)setThePubDate:(NSString *)inPubDate;
- (void)setTheAuthor:(NSString *)inAuthor;
- (void)setTheImageLink:(NSString *)inImageLink;

@end

Articles.m / p>

  #importArticles.h

@implementation文章

@综合喜好;
@synthesize title;
@synthesize summary;
@synthesize mainLink;
@synthesize pubDate;
@synthesize author;
@synthesize imageLink;

- (void)dealloc {
NSLog(@article dealloc \\\
);
[self.title release];
[self.mainLink release];
[self.summary release];
[self.pubDate release];
[self.author release];
[self.imageLink release];

[super dealloc];
}



- (id)init {

self = [super init];
if(self){
//设置您的属性...
self.title = [[[NSMutableString alloc] init] autorelease];
self.mainLink = [[[NSMutableString alloc] init] autorelease];
self.summary = [[[NSMutableString alloc] init] autorelease];
self.pubDate = [[[NSMutableString alloc] init] autorelease];
self.author = [[[NSMutableString alloc] init] autorelease];
self.imageLink = [[[NSMutableString alloc] init] autorelease];
self.favorite = NO;
}
return self; (NSString *)inMainLink summary:(NSString *)inSummary
pubDate:(NSString *)inPubDate author(NSString *)inTitle mainLink: :(NSString *)inAuthor imageLink:(NSString *)inImageLink
{
self = [super init];
if(self){
//设置属性...
if(inTitle!= nil){
self.title = inTitle;
}

if(inMainLink!= nil){
self.mainLink = inMainLink;
}

if(inSummary!= nil){
self.summary = inSummary;
}

if(inPubDate!= nil){
self.pubDate = inPubDate;
}

如果(inAuthor!= nil){
self.author = inAuthor;
}

if(inImageLink!= nil){
self.imageLink = inImageLink;
}

self.favorite = NO;
}

return self;
}


@end

ADDED:



看看我在主类中有 NSXMLParser 在主类.h文件中我写:

 文章* currentArticle; 

现在在.m文件中解析器didStartElement我分配ant初始化文章在解析器didEndElement发布它 [self.currentArticle release] ;

   - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI :( NSString *)namespaceURI 
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
//复制当前Xml元素名称。
currentElement = [elementName copy];
if([elementName isEqualToString:@item]){
//清除我们的故事项缓存...
self.currentArticle = [[文章alloc] init];
}
[currentElement release];

}

ADDED RELEASE FOR TEST / p>

   - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
//复制当前Xml元素名称。
currentElement = [elementName copy];
if([elementName isEqualToString:@item]){
//清除我们的故事项缓存...
self.currentArticle = [[文章alloc] init];
[self.currentArticle release];
}
[currentElement release];

}

看看我已经添加了 .currentArticle release]; 在初始化和断点后,这里...当我第一次我的应用程序进入这部分代码,它调用init但不调用释放第二次它调用释放?但为什么 ?这不正确



为什么我不使用AUTOLEASE !!! $ p> self.title = [[[NSMutableString alloc] init] autorelease];
self.mainLink = [[[NSMutableString alloc] init] autorelease];
self.summary = [[[NSMutableString alloc] init] autorelease];
self.pubDate = [[[NSMutableString alloc] init] autorelease];
self.author = [[[NSMutableString alloc] init] autorelease];
self.imageLink = [[[NSMutableString alloc] init] autorelease];

我不在这部分代码中使用autorelease,因为我已经读过它带给韭菜,因为当我写应用程序结束时自动释放对象释放的工作!我写了



谢谢!!!

解决方案

您可以删除每个安装程序,如

   - (void)setTheSummary:(NSString *)inSummary 
{

if(self.summary!= nil){
[self.summary release];
}

self.summary = [[NSMutableString alloc] initWithString:inSummary];
}

您已将每个ivar声明为属性,并已合成getter和setter。所以你可以设置标题例如:

  self.title = newTitle; 

这将重新设置新标题并将其分配给标题并释放上一个/ p>

编辑



如果您设置

  self.title = [[NSMutableString alloc] init]; 

可变字符串的instande将被过度保留,因此会有泄漏。



保留将保留计数增加1,这通过属性的声明发生,它将通过调用init来执行。



将其更改为:

  self.title = [[[NSMutableString alloc] init] autorelease]; 

EDIT 2



更改这些构造的初始化:

  if(inTitle == nil){
self.title = [[NSMutableString alloc] init];
}
else
{
[self.title release];
self.title = [[NSMutableString alloc] initWithString:inTitle];
}

To:

  if(inTitle!= nil){
self.title = inTitle;
}

现在添加

  self = [self init]; 

并删除

  [super init]; 

在您的init方法开始 initWithValues; 这将首先为您初始化属性,它减少代码重复,使您的类更小。删除 [super init] 只需要调用NSObject的初始化器一次,你可以通过调用 self = [self init] ;



您使用此模式创建了所谓的指定初始化程序。您可以在此处了解有关初始值设置的详情。



编辑3



为了使您的初学者更好,您应该这样写:

   - (id)init 
{
self = [super init];
if(self){
//设置属性...
}
return self;
}



<$ p (NSString *)inMainLink summary:(NSString *)inSummary
pubDate:(NSString *)inPubDate author:(NSString *)inTitle mainLink: )inAuthor imageLink:(NSString *)inImageLink
{
self = [self init];
if(self){
//设置带有参数的属性...
}
return self;
}

此模式将允许您对指定的初始化程序和/或在初始化器中调用继承层次结构。这将确保如果出现错误并且不将属性设置为错误的实例,则返回nil。


I have written class and want show it to you ...

I think that this class written not correct and thats why I have leeks in my application. First of all the delloc never calls. What can I change in this class to make it better, please help.

Articles.h

#import <Foundation/Foundation.h>

@interface Article : NSObject {
    BOOL favorite;
    NSMutableString * title;  
    NSMutableString * summary;  
    NSMutableString * mainLink;  
    NSMutableString * pubDate;  
    NSMutableString * author;  
    NSMutableString * imageLink;  
}

@property (nonatomic, assign) BOOL favorite;  
@property (nonatomic, retain) NSMutableString * title;  
@property (nonatomic, retain) NSMutableString * summary;  
@property (nonatomic, retain) NSMutableString * mainLink;   
@property (nonatomic, retain) NSMutableString * pubDate;  
@property (nonatomic, retain) NSMutableString * author;  
@property (nonatomic, retain) NSMutableString * imageLink;  

- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
             pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink;


//Setter methods
- (void)setTheTitle:(NSString *) inTitle;
- (void)setTheMainLink:(NSString *) inMainLink;
- (void)setTheSummary:(NSString *) inSummary;
- (void)setThePubDate:(NSString *) inPubDate;
- (void)setTheAuthor:(NSString *) inAuthor;
- (void)setTheImageLink:(NSString *)inImageLink;

@end

Articles.m

#import "Articles.h"

@implementation Article

@synthesize favorite;  
@synthesize title;  
@synthesize summary;  
@synthesize mainLink;
@synthesize pubDate;  
@synthesize author;  
@synthesize imageLink;  

- (void)dealloc {
    NSLog(@"article dealloc \n");
    [self.title release];
    [self.mainLink release];
    [self.summary release];
    [self.pubDate release];
    [self.author release];
    [self.imageLink release];

    [super dealloc];
}



- (id)init {

    self = [super init];
    if(self) {
      // set your properties...
      self.title     = [[[NSMutableString alloc] init] autorelease];
      self.mainLink  = [[[NSMutableString alloc] init] autorelease];
      self.summary   = [[[NSMutableString alloc] init] autorelease];
      self.pubDate   = [[[NSMutableString alloc] init] autorelease];
      self.author    = [[[NSMutableString alloc] init] autorelease];
      self.imageLink = [[[NSMutableString alloc] init] autorelease];
      self.favorite = NO;
    }
    return self;
}

- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
            pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink
{
    self = [super init];
    if(self) {
        // set your properties ...
        if (inTitle != nil) {
            self.title = inTitle;
        }

        if (inMainLink != nil) {
            self.mainLink = inMainLink ;
        }

        if (inSummary != nil) {
            self.summary = inSummary;
        }

        if (inPubDate != nil) {
            self.pubDate = inPubDate;
        }

        if (inAuthor != nil) {
            self.author = inAuthor ;
        }

        if (inImageLink != nil) {
            self.imageLink = inImageLink ;
        }

        self.favorite = NO;
    }

    return self;
}


@end

ADDED:

Look I have NSXMLParser in my main class. In the main class .h file I write:

Article * currentArticle;

Now In .m file when parser didStartElement I alloc ant initialize Article in parser didEndElement I release it [self.currentArticle release]; but delloc not calles.

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 
                                        qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    // Copy current Xml Element name.
    currentElement = [elementName copy];
    if ([elementName isEqualToString:@"item"]) {
        // Clear out our story item caches...
        self.currentArticle = [[Article alloc] init];
    }
    [currentElement release];

}

ADDED RELEASE FOR TEST

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 
                                        qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    // Copy current Xml Element name.
    currentElement = [elementName copy];
    if ([elementName isEqualToString:@"item"]) {
        // Clear out our story item caches...
        self.currentArticle = [[Article alloc] init];
        [self.currentArticle release];
    }
    [currentElement release];

}

look I have added [self.currentArticle release]; right after initialization and put breakpoint here ... When at first time my application enters in this part of code it call init but not call release at second time it call release ? But why ? It's not right

WHY I DON'T USE AUTORELEASE !!!

 self.title     = [[[NSMutableString alloc] init] autorelease];
    self.mainLink  = [[[NSMutableString alloc] init] autorelease];
    self.summary   = [[[NSMutableString alloc] init] autorelease];
    self.pubDate   = [[[NSMutableString alloc] init] autorelease];
    self.author    = [[[NSMutableString alloc] init] autorelease];
    self.imageLink = [[[NSMutableString alloc] init] autorelease];

I do not use autorelease in this part of code because I have read that it brings to leeks, because when I write autorelease the objects releases in the end of application work ! Am I write ???

Thanks !!!

解决方案

You can remove every setter like

- (void)setTheSummary:(NSString *) inSummary
{

    if (self.summary != nil) {
        [self.summary release];
    }

    self.summary = [[NSMutableString alloc] initWithString:inSummary];
}

You've declared every ivar as property already and synthesized getters and setters. So you can set the title for example with:

self.title = newTitle;

This will retatin the newTitle and assign it to title and release the previous(if present) value.

EDIT

If you set properties like

self.title = [[NSMutableString alloc] init];

the instande of the mutable string will get over retained, so there will be leaks.

Retain increases the retain count by 1, this happens through the property's declaration and it will go one up by calling init.

Change it to:

self.title = [[[NSMutableString alloc] init] autorelease];

EDIT 2

Change your initialization of these constructs:

if (inTitle == nil) {
    self.title = [[NSMutableString alloc] init];
}
else
{
    [self.title release];
    self.title = [[NSMutableString alloc] initWithString:inTitle];
}

To:

if (inTitle != nil) {
    self.title = inTitle;
}

Now add

self = [self init];

and remove

[super init];

at the beginning of your init method initWithValues; This will initialize the properties for you first, it reduces code duplication and makes your class smaller. The removal of [super init] is necessary to call the the initializer of NSObject only once, you are doing this by calling self = [self init];.

You've created with this pattern a so called designated initializer. You can read more on initializers here.

EDIT 3

To make your intializers perfect you should write them this way:

- (id)init 
{
    self = [super init];
    if(self) {
       // set your properties...
    }
    return self;
}

and

- (id)initWithValues:(NSString *) inTitle mainLink:(NSString *) inMainLink summary:(NSString *) inSummary
            pubDate:(NSString *) inPubDate author:(NSString *) inAuthor imageLink:(NSString *) inImageLink
{
    self = [self init];
    if(self) {
       // set properties with parameters ...
    }
    return self;
}

This pattern will allow you to react on errors which can occur in your designated initializer and/or in the initializers called up the inheritance hierarchy. This will ensure that a nil is returned if something goes wrong and you don't set properties to an erroneous instance.

这篇关于类工作不正确。如何使它更好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆