2016-02-03 13 views
11
Kullanmadan

mevcut cihaz ekranının bir UIImage anlık döndüren özel C işlevi _UICreateScreenUIImage, düşünün böylece:Erişim Özel UIKit Fonksiyon Bridging Başlığını

BenimUygulamam-Köprü-Header.h

@import UIKit; 
UIImage *_UICreateScreenUIImage(void) NS_RETURNS_RETAINED; 

MyClass.swift

let image = _UICreateScreenUIImage() 
print(image) // <UIImage: 0x7fc4ba6081c0>, {375, 667} 

Köprüleme üstbilgisi kullanmadan _UICreateScreenUIImage numaralı parolaya erişebilmemin bir yolu var mı?

bir başlangıç ​​düşünce UIImage bir uzantısı oluşturmak için, ama uzatma uzantısında fonksiyonun gövdesini ilan etmek beni bekliyor: _UICreateScreenUIImage olmadığından,

extension UIImage { 
    public func _UICreateScreenUIImage(_: Void) -> UIImage // "Expected '{' in body of function declaration" 
} 

Bu uygulama zaten kusurludur UIImage'da bir yöntem.

Bu yöntemin ifşa edilmesi ve erişilmesi saf Swift'de mümkün mü?


Kişiler, "Ekran görüntüsünü nasıl alabilirim?" Sorusuyla kafam karışıyor gibi görünüyor. Benim sorduğum bu değil. Swift'de UIImage *_UICreateScreenUIImage(void); gibi yöntemlere nasıl erişebilirim diye soruyorum. +(UIImage *)_deviceSpecificImageNamed:(NSString *)name inBundle:(NSBundle *)bundle; veya +(UIImage *)_pu_PhotosUIImageNamed:(NSString *)name; gibi herhangi bir özel yöntem olabilir. @asmname, bu yüzden buna göre ayarlamak için hazır olacak aslında sadece 2.3 değiştirildi @_silgen_name için inşa vardır,

@asmname("_UICreateScreenUIImage") 
func _UICreateScreenUIImage() -> UIImage 

// That's it – go ahead and call it: 
_UICreateScreenUIImage() 

O sırada da:

cevap

14

Bu umduğunuzdan daha çok daha kolay

@_silgen_name("_UICreateScreenUIImage") 
func _UICreateScreenUIImage() -> UIImage 

Benim bildiğim kadarıyla, @_silgen_name, Objective-C yöntemlerinin çözünürlüğünü sağlamaz.

let invokeImageNamed: (String, NSTimeInterval) -> UIImage? = { 
    // The Objective-C selector for the method. 
    let selector: Selector = "animatedImageNamed:duration:" 
    guard case let method = class_getClassMethod(UIImage.self, selector) 
     where method != nil else { fatalError("Failed to look up \(selector)") } 

    // Recreation of the method's implementation function. 
    typealias Prototype = @convention(c) (AnyClass, Selector, NSString, NSTimeInterval) -> UIImage? 
    let opaqueIMP = method_getImplementation(method) 
    let function = unsafeBitCast(opaqueIMP, Prototype.self) 

    // Capture the implemenation data in a closure that can be invoked at any time. 
    return { name, interval in function(UIImage.self, selector, name, interval) } 
}() 

extension UIImage { 
    // Convenience method for calling the closure from the class. 
    class func imageNamed(name: String, interval: NSTimeInterval) -> UIImage? { 
     return invokeImageNamed(name, interval) 
    } 
} 

UIImage.imageNamed("test", interval: 0) 

Bildiğim kadarıyla NS_RETURNS_RETAINED taşıma gibi bu sizin için oluşturulur olmayacak: Bunun için, hatta ve hatta güçlü Objective-C çalışma zamanı API yoktur. Bunun yerine, kolaylık bir işlevde olduğu Unmanaged bir dönüş türü kullanın ve sarabilirsiniz: Bu işler

@_silgen_name("_UICreateScreenUIImage") 
func _UICreateScreenUIImage() -> Unmanaged<UIImage> 
func UICreateScreenUIImage() -> UIImage { 
    return _UICreateScreenUIImage().takeRetainedValue() 
} 
+1

! Şaşırtıcı! Asmname ve '_silgen_name' nerede belgeleniyor? Swift'deki extern C'nin karşılığı mı? – JAL

+2

Bilgim için belgelenmemiş (LLVM'nin dahili bölümlerinin dışında). 'Asmname' terimi, gerçekten de 'extern' ile eşdeğer olduğunu gösterecektir, çünkü montajcıya sembolün başka bir yerde aramasını söyler. '_silgen_name', daha spesifik olarak, SIL nesli sırasında" yerleşik ""() "beyanları üreteceği anlamına gelir (ki bu da, 'extern' benzeri assembler tarafından çözülür). –

+2

Çok teşekkür ederim! Bunu kabul edildi olarak işaretlemeyi ve size ödül vermeyi bekliyorum. Başka bir takip sorusu: 'UIImage' üzerinde özel bir sınıfa erişmek istediğimde, örneğin: + (UIImage *) _ pu_PhotosUIImageNamed: (NSString *) name; '?Bu aynı modeli takip eder mi? – JAL