NS: записать адрес памяти объекта в метод переопределенного описания

Я переопределяю метод описания объекта. Мне нужно знать, как напечатать адрес памяти объекта, чтобы заменить {???} в приведенном ниже коде:

-(NSString *) description {
    return [NSString stringWithFormat:@"<SomeClass: %@>\nparmeterOne: %@\nparameterTwo: %@",
            {???}, self.parameterOne, self.paramterTwo];
}

Я хочу, чтобы он напечатал в консоли вот так:

<SomeClass: 0x4c05600> parameterOne: 12 parameterTwo: sausages

person Undistraction    schedule 26.09.2011    source источник


Ответы (2)


Чтобы напечатать адрес, используйте спецификатор формата %p и собственный указатель:

-(NSString *) description {
    return [NSString stringWithFormat:@"<SomeClass: %p>\nparmeterOne: %@\nparameterTwo: %@",
            self, self.parameterOne, self.paramterTwo];
}
person Vladimir    schedule 26.09.2011
comment
Хороший. Я думал, что это вызовет рекурсию. Большое спасибо. - person Undistraction; 26.09.2011
comment
использование self со спецификатором '% @' действительно вызовет рекурсию, так как это снова вызовет вызов метода -description. Спецификатор% p просто выводит адрес указателя - person Vladimir; 26.09.2011
comment
Я склоняюсь к [NSString stringWithFormat:@"%@ parameterOne:...", [super description], ...]; - адрес заканчивается там, потому что он есть у NSObject, но вы также не выбрасываете ничего, что, по вашему мнению, имеет отношение к отладке в любых суперклассах, от которых вы можете наследовать. - person Tommy; 03.06.2013
comment
Дополнительное примечание: %p ожидает указатель типа void *, вы должны привести self обратно к void *, иначе произойдет неопределенное поведение. - person ; 03.06.2013
comment
@ user529758: нет необходимости приводить, нет неопределенного поведения. void * и id внутренне почти одинаковы, и в этом случае нет никакой разницы, преобразовываете ли вы его в void * или нет. - person Michael; 18.04.2014
comment
Вы должны поставить символ '&' перед аргументом 'self' - person Artem Deviatov; 13.10.2015
comment
Существует разница между адресом объекта, когда self и &self. Вам нужно поставить &. - person Nik Kov; 13.04.2017
comment
@NikKov, зачем тебе это? self уже является указателем на текущий объект. - person Vladimir; 13.04.2017
comment
@Vladimir Хорошо, ты прав. Но в случае объектной переменной это необходимо. Например, в методе cellForRowAtIndexPath для tableView, если вы напишете NSString *ident = @"identificator"; NSLog(@"%p", ident), это будет один и тот же адрес для каждой ячейки. Бит с NSLog (@% p, & identify) будет другим адресом для каждой ячейки. - person Nik Kov; 13.04.2017
comment
@NikKov, не совсем. NSString identity = @identificator - это особый случай - он создается как класс __NSCFConstantString, поэтому все равные строковые литералы будут использовать один и тот же адрес памяти для оптимизации использования памяти. & Идентификатор получит адрес локальной переменной, указывающей на NSString, и будет иметь тип NSString ** - person Vladimir; 14.04.2017

Самый простой способ - использовать суперописание

- (NSString *)description
{
    return [NSString stringWithFormat:@"%@ Area: %@, %@", [super description], self.identifier, self.name];
}

Таким образом, в случае этого объекта модели, который является подклассом NSObject, вы можете избежать лишней работы и запоминания %p.

Вручную с помощью NSStringWithClass () и% p

- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@: %p> Area: %@, %@", NSStringFromClass([self class]), self, self.identifier, self.name];
}

Таким образом, в случае объектной модели, в которой у вас есть конкретный исполнитель, производный от этого класса, вы покажете правильное имя класса.

person Cameron Lowell Palmer    schedule 10.12.2013