What Is the Swift Equivalent of -[Nsobject Description]

What is the Swift equivalent of -[NSObject description]?

To implement this on a Swift type you must implement the CustomStringConvertible protocol and then also implement a string property called description.

For example:

class MyClass: CustomStringConvertible {
let foo = 42

var description: String {
return "<\(type(of: self)): foo = \(foo)>"
}
}

print(MyClass()) // prints: <MyClass: foo = 42>

Note: type(of: self) gets the type of the current instances instead of explicitly writing ‘MyClass’.

Getting description like NSObject

From the println() API documentation:

/// Writes the textual representation of `object` and a newline character into
/// the standard output.
///
/// The textual representation is obtained from the `object` using its protocol
/// conformances, in the following order of preference: `Streamable`,
/// `Printable`, `DebugPrintable`.
///
/// Do not overload this function for your type. Instead, adopt one of the
/// protocols mentioned above.
func println<T>(object: T)

So in order to get a custom println() representation, your class must (e.g.) adopt the Printable protocol explicitly:

class Test : Printable {
var description:String {
return "This is Test"
}
}

However, this does not work in a Playground of Xcode 6.1.1.
It has been fixed in Xcode 6.3 beta. From the release notes:

• Adding conformances within a Playground now works as expected, ...

I could not find this in the API headers, but it seems that NSObject
(and its subclasses) are already known to conform to Printable.
Therefore the custom description works for your Test1 class.


In Swift 2 (Xcode 7), the Printable protocol has been renamed
to CustomStringConvertible:

class Test : CustomStringConvertible {
public var description:String {
return "This is Test"
}
}

let t = Test()
print(t)
// This is Test

whats the swift equivalent of NSObject Protocol ?

You can do this a couple of ways. First, you can make Consumer generic:

class Consumer<T: NSObject where T: Prototest> {
var protoInstance: T?
var protoInstance2: T?
}

If you do that, then all references to protoInstance or protoInstance2 will inherit from NSObject, and you will be able to call methods like .copy() directly on the object.

If you don't want Consumer to be generic, you can enforce restraints on the init methods using generic parameters, like this:

class Consumer {
// ...
init<T: NSObject where T: Prototest>(x: T) {
protoInstance = x
}
}

If you do that, you will be guaranteed that protoInstance will be an NSObject, but you will have to cast to NSObject to use any of NSObject's methods:

func doSomething() {
if let x = protoInstance as? NSObject {
x.copy()
}
}

Edit:

Note that I wasn't sure if you really wanted protoInstance and protoInstance2 to be of different types I was a little unclear from your question. If you do want them to be different types, I can add additional suggestions to this answer.

Swift: Unable To Set Description on Subclass of NSObject

Look at where description is defined. It is listed in the NSObjectProtocol as

public var description: String { get }

You can only get the description property, you can't set it.

In Objective-C, description is implemented in most classes as a method; it has no underlined storage. The swift equivalent would be a computed property:

public override var description: String {
return "I'm an object"
}

tl;dr Use a computed property instead of a stored property

class CustomObject : NSObject {
private var des: String
override var description: String {
get {
return des
}
set(newValue) {
des = newValue
}
}

init(string: String) {
des = string
}
}

[NSObject description]

The description of the instance gives you information about the specific instance you have created.

- (NSString *)description;

NSString *string = [NSString alloc] initwithString:@"aString"]];
[string description];

Gives you information about this instance (location in memory etc)

On the other side:

+ (NSString *)description;

[NSString description];

Gives you information about the class NSString.

The same rules apply to all NSObject subclasses and other classes that conform to NSObject protocol such NSArray, NSDictionary *NSProxy* etc

Overriding description method in NSObject on swift


  • description is a (computed) property of NSObjectProtocol, not a method.
  • Its Swift view returns a String, not NSString.
  • Since you are overriding a property of a superclass, you must specify override explicitly.

Together:

// main.swift:
import Foundation

class Rectangulo: NSObject {

var ladoA : Int
var ladoB : Int
var area: Int {
get {
return ladoA*ladoB
}
}

init (ladoA:Int,ladoB:Int) {

self.ladoA = ladoA
self.ladoB = ladoB
}

override var description : String {
return "El area es \(area)"
}
}

let r = Rectangulo(ladoA: 2, ladoB: 3)
print(r) // El area es 6

hash() and description() not allowed in Xcode 6.3 for NSObject

As the error says, in both cases there's a naming conflict between a property and a method. The most obvious way to fix is by turning your 2 methods into properties:

public override var hash: Int {
return self.hashValue
}

public override var description: String {
return EVReflection.description(self)
}

which can also be written as:

public override var hash:Int {
get {
return self.hashValue
}
}
public override var description : String {
get {
return EVReflection.description(self)
}
}

The reason why it worked in the previous version is most likely because of this:

Swift now detects discrepancies between overloading and overriding in the Swift type system and the effective behavior seen via the Objective-C runtime.

Read more in the release notes (search for 18391046 and 18383574)



Related Topics



Leave a reply



Submit