IPhone SDK: правильный способ вернуть UILabel без выделения - PullRequest
1 голос
/ 05 ноября 2010

В настоящее время у меня есть некоторый код, который выглядит следующим образом:

-(UIView)someMethod {
  CGRectMake(0,0,100,100);
  UILabel *label = [[UILabel alloc] initWithFrame:rect];
  return label;
}

Хотя он работает , он, очевидно, приводит к утечке памяти и требует исправления.Я думал , что исправление будет:

UILabel *label = [UILabel initWithFrame:rect];

Но компилятор говорит мне, что UILabel не отвечает на initWithFrame.Я думаю, мой вопрос состоит из двух частей:

a) Как правильно сделать это, чтобы у меня не было утечки памяти?

и

b) I 'Я не понимаю, почему [UILabel alloc] будет отвечать на initWithFrame, но не на UILabel сам по себе (насколько я понимаю, UILabel наследуется от UIView, который отвечает на initWithFrame).

Ответы [ 4 ]

4 голосов
/ 05 ноября 2010

а) Вы не можете избежать +alloc. Но вы можете использовать -autorelease, чтобы отказаться от владения.

-(UIView*)someMethod {
  CGRect rect = CGRectMake(0,0,100,100);
  UILabel *label = [[[UILabel alloc] initWithFrame:rect] autorelease];
  return label;
}

b) +alloc - метод класса, а -initWithFrame: - метод экземпляра. Последний может быть вызван только на (или, в терминологии ObjC, отправлен на экземпляр UILabel. Однако символ «UILabel» является классом, а не экземпляром, поэтому [UILabel initWithFrame:rect] не будет работать. Точно так же метод класса, такой как +alloc, может быть вызван только для класса, поэтому [label alloc] не будет работать.

2 голосов
/ 05 ноября 2010

Может быть, больше похоже на:

-(UILabel)someMethod {

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,100)];
    return [label autorelease];
    }
1 голос
/ 05 ноября 2010

а)

 -(UIView *)someMethod {
    return [[[UILabel alloc] initWithFrame:CGRectMake(0,0,100,100)] autorelease];
}

b) вы неправильно понимаете разницу между методом класса и методом экземпляра.

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

// declaration: notated with +
+ (NSDocumentController *)sharedDocumentController;
// usage
NSDocumentController * thang = [NSDocumentController sharedDocumentController];

метод экземпляра объявлен и используется следующим образом:

// declaration: notated with -
- (id)init;
// usage:
// + alloc is a class method
//     this requests the class (NSObject) to allocate and return a newly allocated NSObject
// - init is the instance method
//     this sends a message to the NSObject instance (returned by [NSObject alloc])
NSObject * thang = [[NSObject alloc] init];

в вашем примере alloc возвращает выделенный экземпляр, для которого вы должны затем вызвать соответствующий метод экземпляра init.

некоторые классы предоставляют удобные конструкторы, которые часто возвращают автоматически выпущенный экземпляр:

+ (NSNumber *)numberWithInt:(int)anInt;

но дублирование кода таким способом не очень распространено, если только вы не работаете с такими сложными темами, как кластеры классов. Конечно, было бы неплохо добавить это в интерфейс, если вы обнаружите, что вам регулярно нужны определенные функции или конструктор удобства.

0 голосов
/ 05 ноября 2010

Просто используйте ваш оригинальный метод и используйте

return [label autorelease];

вместо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...