Đã đạt được thỏa thuận UIPopovercontroller trong khi cửa sổ bật lên vẫn hiển thị


111

Tôi đảm bảo với bạn rằng tôi đã tìm kiếm câu trả lời trong SO cho câu hỏi của mình nhưng không có câu trả lời nào hữu ích. Ở đây tôi có một mã đơn giản sẽ hiển thị UIImagePickerControllertrong một 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];
}

Bây giờ, ngay cả từ lần đầu tiên tôi nhận [UIPopoveController dealloc]được trong khi ... lỗi và chương trình bị treo. Tôi không thực hiện bất kỳ hoạt động lưu giữ, chuyển nhượng lại hoặc tự động đăng ký nào theo ARC. Có bất kỳ cân nhắc đặc biệt UIPopoverControllersnào khi hưởng lợi từ ARC không?

Câu trả lời:


203

UIPopoverControllers phải luôn được giữ trong một biến thể hiện. Đó là một thực hành tốt để tạo ra một đặc tính mạnh mẽ cho nó.

CẬP NHẬT:

Kể từ iOS 8, bạn nên sử dụng UIPopoverPresentationController. Sau đó, bạn không cần phải giữ một tham chiếu đến cửa sổ bật lên vì nó được quản lý bởi bộ điều khiển bản trình bày.

Ví dụ về mã (hoạt động cả trên iPhone và 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
Ồ, tôi hiểu rồi. Nhưng đây không phải là một UIAlertView? Tôi không bao giờ có ivar cho nó, tôi chỉ cấp phát nó ở bất cứ đâu tôi cần, hiển thị nó và sau đó [dùng để] phát hành. Popovercontroller khác nhau ở điểm nào?
Mikayil Abdullayev

17
@Mikayil Cảnh báo được giữ lại bởi superview của nó (như tất cả các chế độ xem), nhưng popoverController không phải là một chế độ xem, do đó không có superview, vì vậy sẽ không được ai giữ lại nếu bạn không giữ lại nó (hoặc lưu trữ nó trong một biến mạnh có phạm vi dài hơn phương thức hiện tại - ví dụ: iVar).
fzwo

1
Nhưng tôi vẫn nhầm lẫn về số lượng giữ lại của UIPopoverController. Bởi vì tôi đã kiểm tra trước khi phân bổ và bắt đầu một. Và chỉ khi nó bằng không, tôi sẽ phân bổ một cái mới. Nhưng sau khi phân bổ nó lần đầu tiên, tôi không bao giờ nhận được nó. Ý tôi là tôi gọi một phương thức một lần. Ở đó tôi phân bổ và bắt đầu ivar của mình. Và lần sau khi tôi gọi lại phương thức đó lần này tôi thấy ivar của mình đã được cấp phát. Nếu ARC đảm nhận việc này, thì khi nào nó sẽ phát hành nó. Hay nó tự động tìm nó?
Mikayil Abdullayev

@Mikayil ivars được phát hành bởi ARC khi đối tượng được deallocated hoặc khi bạn đặt chúng vào con số không
Felix

nhưng họ đã không đề cập đến điều này trong các tài liệu, trong Làm thế nào để sử dụng phần họ sử dụng biến cục bộ
Amit Battan

11

Khi hàm thoát ra, không có tham chiếu nào khác đến bộ điều khiển bật lên, vì vậy nó được phân bổ quá sớm.

Hãy thử thêm nó làm thành viên trong lớp của bạn.

Tim


Không phải tôi vẫn có thể nhìn thấy nó trước khi nó được phân bổ?
Mikayil Abdullayev

10

Thêm nội dung @ phix23 đã trả lời, tạo thuộc tính * poc như thế này:

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

và sau đó thay đổi

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

cho

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

11
Bạn không cần phải đặt nó vào tệp .h của mình. Điều đó sẽ công khai nó và trừ khi bạn muốn điều đó, chỉ cần đặt nó thành một thuộc tính trong tệp .m của bạn.
Joshua Dance
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.