设置属性和委托 - 何时使用自己?

时间:2011-10-01 11:38:09

标签: iphone objective-c properties protocols

我正在处理NSXMLParser示例代码,我有几个关于如何设置委托和属性的问题,特别是在AppDelegate中。

在界面中,AppDelegate被声明为跟随NSXMLParserDelegate protocol,但它似乎没有实现任何协议方法或在任何时候将自己设置为委托。这些似乎属于ParseOperation类。这只是一个错字吗?

@interface SeismicXMLAppDelegate : NSObject <UIApplicationDelegate, NSXMLParserDelegate> {
    UIWindow *window;
    UINavigationController *navigationController;
    RootViewController *rootViewController;

@private
    // for downloading the xml data
    NSURLConnection *earthquakeFeedConnection;
    NSMutableData *earthquakeData;

    NSOperationQueue *parseQueue;
}

该接口还声明了一些私有属性。这些在.m文件的接口扩展中再次定义。

@interface SeismicXMLAppDelegate ()

@property (nonatomic, retain) NSURLConnection *earthquakeFeedConnection;
@property (nonatomic, retain) NSMutableData *earthquakeData;    // the data returned from the NSURLConnection
@property (nonatomic, retain) NSOperationQueue *parseQueue;     // the queue that manages our NSOperation for parsing earthquake data

- (void)addEarthquakesToList:(NSArray *)earthquakes;
- (void)handleError:(NSError *)error;
@end

好吧,我想我明白这意味着其他类无法访问这些属性,在这种情况下这似乎是一件非常好的事情。这是一个谜 - 在applicationDidFinishLaunching:的实现中,使用不同的符号定义了两个属性。

self.earthquakeFeedConnection =
[[[NSURLConnection alloc] initWithRequest:earthquakeURLRequest delegate:self] autorelease];

VS

parseQueue = [NSOperationQueue new];

为什么一个人使用self.propertyName =而另一个人使用propertyName =?我知道parseQueueearthquakeFeedConnection最终都会将保留计数设为1,但earthquakeFeedConnectionautorelease pool的一部分会自动释放,而我们会自动释放由于使用parseQueue而未调用+new,因此必须稍后发布autorelease

内存考虑并不能解释自我的使用。还有其他区别吗?

2 个答案:

答案 0 :(得分:1)

allocnew返回保留一次的对象。 init对内存管理没有任何影响,autorelease将稍后释放该对象

如果您编写self.myProperty = ...,则会调用synthesized setter,其行为与您在相应属性nonatomic, retain中定义的行为相同。 nonatomic表示getter和setter不是线程安全的(但很快)。 retain表示在这种情况下,setter将释放旧对象并保留新对象。如果您编写assign而不是retain,则setter只会分配指针,并且不会在受影响的对象上调用release或retain。

您的示例中的目标是创建两个保留一次的对象 例1:

self.earthquakeFeedConnection = [[[NSURLConnection alloc] initWithRequest:earthquakeURLRequest delegate:self] autorelease];
  • 在alloc:retainCount:1
  • 之后 自动释放后
  • :retainCount:1-1(减一意味着:稍后发布)
  • 调用setter后:retainCount:2-1

例2:

parseQueue = [NSOperationQueue new];

  • new:retainCount:1

所以最后两种情况都会产生相同的结果。你也可以写

earthquakeFeedConnection = [[NSURLConnection alloc] initWithRequest:earthquakeURLRequest delegate:self];

setter-solution看起来更复杂但有一些副作用。如果您稍后注意到在getter或setter中需要特殊行为(例如:触发其他一些方法或进行一些值检查:NSString只应包含eMail-Addresses),那么您只需要覆盖getter或setter。如果您不使用self.myProp = ...,那么您必须搜索使用情况,并且还必须更改该代码段。

委托 - 东西:是的,你是对的:通常你必须(或应该)在接口定义中列出alle实现的协议,但NSURLConnectionDelegate是一个例外。我不知道为什么(我在NSObject - class-reference中找不到实现点),但每个NSObject都已实现该委托。因此,您不必提及您的类正在实现该委托。

答案 1 :(得分:0)