Угода UIPopovercontroller досягнута, поки popover все ще видно


111

Я запевняю вас, що я шукав відповідь в ТА на своє запитання, але жодна з них не була корисною. Тут я отримав простий код, який повинен бути представлений у UIImagePickerControllerмежах UIPopoverController:

-(void)takePicture:(id)sender{
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing=YES;
UIPopoverController *poc=[[UIPopoverController alloc] 
                            initWithContentViewController:picker];
[poc presentPopoverFromBarButtonItem:bbItem 
            permittedArrowDirections:UIPopoverArrowDirectionAny
                            animated:NO];
}

Зараз, навіть з першого разу, коли я потрапляю [UIPopoveController dealloc]під час ... помилки, і програма виходить з ладу. Я не виконую жодних ретрансляційних, повторних чи авторелізів відповідно до АРК. Чи є якесь особливе врахування UIPopoverControllersпри вигоді від ARC?

Відповіді:


203

UIPopoverControllers завжди має містити змінну примірника. Доброю практикою є створення для нього сильної властивості.

ОНОВЛЕННЯ:

Станом на iOS 8 ви повинні використовувати UIPopoverPresentationController. Тоді вам не потрібно зберігати посилання на поїзд, оскільки ним керує контролер презентації.

Приклад коду (працює як на iPhone, так і на iPad):

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = YES;
picker.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController* popoverPC = picker.popoverPresentationController;
popoverPC.barButtonItem = bbItem;
popoverPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:picker animated:YES completion:nil];

1
О Я бачу. Але це не схоже на UIAlertView? Я ніколи не маю ivar для цього, я просто виділяю його у будь-якому місці, показую його, а потім [звик] звільняти. Чим відрізняється Popovercontroller?
— Мікаїл Абдуллаєв

17
@Mikayil AlertView зберігається під наглядом (як і всі перегляди), але popoverController не є переглядом, тому не має перегляду, тому його ніхто не зберігатиме, якщо ви не збережете його (або зберігайте його у сильній змінній, яка має область, що довша, ніж поточний метод - наприклад, iVar).
— fzwo

1
Але я все ще плутаюся щодо кількості залишків UIPopoverController. Тому що я ставлю чек перед тим, як виділити та ініціювати. І тільки якщо це нуль, я виділяю нове. Але після виділення його вперше я ніколи не отримую його нульовим. Я маю на увазі, що я викликаю метод один раз. Там я виділяю і ініціюю свій івар. І наступного разу, коли цього разу я знову закликаю цей метод, я знаходжу свій івар вже виділений. Якщо ARC піклується про це, то коли це випускає. Або це автоматично випускає?
— Мікаїл Абдуллаєв

@Mikayil ivars випускається ARC, коли об’єкт розміщений або коли ви встановите їх на нуль
— Фелікс

але вони не згадували про це в документації, у розділі " Як користуватися " вони використовують локальну змінну
— Amit Battan

11

Коли функція завершується, немає іншого посилання на контролер, що займається перехопленням, тому це занадто рано розміщується.

Спробуйте додати його як члена свого класу.

Тім


Чи не можу я ще встигнути її побачити першою, перш ніж вона перейде до місця розташування?
— Микаїл Абдуллаєв

10

Додавши відповідь @ phix23, створіть властивість * poc так:

@property (nonatomic, retain) IBOutlet UIPopoverController *poc;

а потім змінити

UIPopoverController *poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];

для

self.poc = [[UIPopoverController alloc] 
                            initWithContentViewController:picker];

11
Не потрібно вносити його у свій .h файл. Це зробить його загальнодоступним, і якщо ви цього не хочете, просто зробіть його властивістю у вашому .m файлі.
— Танець Джошуа
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.