10
@interface SomeClass : NSObject

@property (copy,   nonatomic) NSString *usefulString;
@property (strong, nonatomic) NSString *dangerousString;

@property (copy,   nonatomic) NSURL *curiousURLOne;
@property (strong, nonatomic) NSURL *curiousURLTwo;

@end

在上面的类中,dangerousString被认为是一个坏主意,因为NSMutableString继承自NSString. 这意味着您的类的用户可能会将可变字符串设置为dangerousString,然后稍后将可变字符串的值从SomeClass. 该属性usefulString没有这种危险,因为它将值复制到一个新的(不可变的)字符串对象中。

NSURL但是,对于(以及任何其他没有可变对应物的基础类 - 例如NSNumber),属性声明的复制语义似乎是不必要的。NSURL确实符合 NSCopying 的copyWithZone: (......但我不得不怀疑它是否不只是返回相同的对象并增加了保留计数 - 为什么它会做其他任何事情?)

你为什么要声明copy没有变异危险的属性?

4

2 回答 2

9

在 iOS7 中你可以使用 NSURLComponents,现在它很简单,看这个例子:

NSString *urlString = @"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];

NSLog(@"%@ - %@ - %@ - %@", components.scheme, components.host, components.query, components.fragment);



NSURLComponents *components = [NSURLComponents new];
[components setScheme:@"https"];
[components setHost:@"mail.google.com"];
[components setQuery:@"shva=1"];
[components setFragment:@"inbox"];
[components setPath:@"/mail/u/0/"];

[webview loadRequest:[[NSURLRequest alloc] initWithURL:[components URL]]];
于 2014-02-26T18:12:40.213 回答
6

Apple 不提供可变子类这一事实并不意味着恶意用户无法专门构建一个来欺骗您的类。如果您在假设字符串可以在您的类的背后更改的假设下操作,您至少需要允许恶意用户扩展NSURL到可变类的可能性:

@interface TrickThemURL : NSURL
    // override key properties, such as baseURL and host, to be mutable
@end

如果程序员给了你一个对象,TrickThemURL而你在验证之前没有复制它,那么程序员现在可以自由地更改 URL 而不会让你的类知道。

于 2012-12-21T03:02:28.967 回答