什么是NSMutable Array / String / URL?

时间:2015-09-25 07:44:54

标签: ios swift cocoa

有时我将变量定义为NSArray/String/URL时会出错,通常可以通过将其更改为NSMutableArray/String/URL来解决。

他们之间有什么区别?人们说你不能改变NSString的价值,但为什么不改变,因为我把它定义为var的变量?

请使用Swift 2代码进行说明。

这里的代码示例:

enum Router: URLRequestConvertible {

    static let baseURLString = "https://api.500px.com/v1"
    static let consumerKey = "My_Key"

    case PopularPhotos(Int)
    case PhotoInfo(Int, ImageSize)
    case Comments(Int, Int)

    var URLRequest: NSURLRequest {
    //Error: Type does not conform to protocol 'URLRequestConvertible' with Alamofire. 
    //I solved this problem by changing it to NSMutableRequest. 

        let (path, parameters) : (String, [String: AnyObject]) = {

            switch self {

            //3 cases. 

            }
        }()

        let URL = NSURL(string: Router.baseURLString)
        let URLRequest = NSURLRequest(URL: URL!.URLByAppendingPathComponent(path))
        let encoding = Alamofire.ParameterEncoding.URL

        return encoding.encode(URLRequest, parameters: parameters).0
    }
}

3 个答案:

答案 0 :(得分:3)

NS类型来自Cocoa(有些人会说Objective-c,但实际上它们并不存在于Objective-C中,所以它们是在NextStep库中创建的,然后Apple在购买NextStep之后在Cocoa中使用 - >因此NS前缀)

NSArray / String / URL类似于let myVar =“aString”

NSMutableArray / String / URL类似于var myVar =“aString”

第一个不能改变后,它设置第二个即可。为什么使用Cocoa / Objective-C类型而不是本机Swift类型?

编辑(见评论)

在Swift中你可以定义一个字符串:

var anEmtpyString = String()

var anEmtpyString = ""

在第二种情况下,Swift非常聪明,可以推断出类型是String。如果使用'var',则字符串为Mutable,这意味着您可以在之后更改它。所以我可以这样做:

var myString = "first text"
myString = "another text"

如果您使用'let',则会创建对字符串的引用,也称为Immutable

let myString = "first text"
myString = "another text" // <- the compiler won't accept this !

在这些例子中,我使用了Swift中的原生String类型,它存在于Swift 1.2和2中

我也可以使用Cocoa / Objective类型NSString,NSMutableString,但大部分时间都不需要它。如果您使用的是用Objective-C编写的框架,那么它会很方便。因为你不必从String转换为NSString / NSMutableString,因此对你来说更容易。 (当然可以)

在Objective-C中没有let或var关键字,所以你使用了NSString(for let)和NSMutableString(for var)。

NSArray / NSMutableArray也是如此

更多信息:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

PS来自gnasher729的答案更具技术性,并告诉你它是如何在幕后进行的。它与指针有关,指针在Objective-C中非常存在,但在Swift中更加隐藏。如果你来自一个学习指针的背景,它会使事情更清晰,如果不是,我不确定它是否会对你有所帮助。如果您希望我对此进行扩展,请告诉我们。

答案 1 :(得分:1)

一个。

在Objective-C中,许多类型的日常例程都不是内置类型。这意味着它们不是编程语言的一部分。

因此,框架Foundation将类型定义为类,与任何其他类一样。与NSImageNSManagedObjectNSWhatever等类没有区别。您没有语言级文档。它们被记录为框架的一部分。您可以将它们视为每个其他类,包括子类,类别等等。他们根本没什么特别的。 (你可以完全取代它们,但没有理由这样做。)

在Objective-C中,每个实例对象都在堆上分配(“动态”)。由于NSString的实例是常见的实例对象,因此您也可以使用它们。此类构造的返回值不是实例对象,而是对实例对象的引用。这意味着包含NSString实例的所有实例对象都被“引用”处理。

使用“字符串类型”定义变量时,不要定义字符串实例,而是定义字符串的引用:

NSString *referenceToString;

这个引用总是一个变量。在Swift中它看起来像这样:

var string : String;

使用关键字const定义Objective-C中const的类比。

NSString * const referenceToString; 

但是有一个很大的区别:因为你声明的变量是一个引用,所以constness可以与引用或对象相关。在第一种情况下,您无法更改引用,在后一种情况下,您无法更改对象。上述语法表示:对NSString实例的常量引用。因此,您不能为该引用分配值。 (例如,引用另一个字符串对象。)

这些常量引用在Objective-C中不是很流行,因为在大多数情况下,引用的常量是没有意义的。

字符串 object 本身的常量由字符串对象的类型建模。 NSString表示常量字符串对象NSMutableString表示变量字符串 object

因此,如果您想要一个可以变异的刺痛,请使用NSMutableString而不是NSString

NSMutableString *referenceToAMutableString;
NSString *referenceToAnImmutableString;

答案 2 :(得分:0)

有值对象和引用对象。例如,Int和String是值对象,NSNumber和NSString是引用对象。 Swift struct实例是值对象,Swift类实例是引用对象。

对于参考对象,变量对象。它是对象的引用。因此,“let”变量不能更改,这意味着它引用一个对象而不能使其引用另一个对象。可以更改“var”变量,这意味着可以使其引用不同的对象。但两者都没有对物体本身说什么。无法修改NSArray对象,可以修改NSMutableArray。使用let或var变量来引用对象只意味着变量不能或不能引用不同的变量,它没有说明是否可以修改对象本身。