Swift'de bir iOS uygulamasında çalışıyorum (çoğu Objective-C'den taşındı). Çekirdek Verileri kullanıyorum ve modelimden otomatik olarak oluşturulan sınıflara işlevsellik eklemek için uzantıları kullanmaya çalışıyorum. Objective-C'de hazırladığım bir şey, A sınıfındaki bir kategoride bir yöntem eklemek ve bu yöntemi, B sınıfındaki (A'dan türetilen) bir kategoride geçersiz kılmaktı ve aynı şeyi Swift'de yapmayı umuyordum. Bir süreSwift'deki uzantılar arasında geçersiz kılınabilir veya değil mi? (Derleyici karışık görünüyor!)
şimdi Projemde aşağıdaki kodu yaşadım (ve bu sadece bir örnektir) ve ben işlev henüz kullanmadıysanız bile, derleyici gayet güzel bu kodu derleme çalıştı:
// From CellType.swift -- NOTE: Imports from Foundation and CoreData
@objc(CellType)
class CellType: NSManagedObject {
@NSManaged var maxUses: NSNumber
@NSManaged var useCount: NSNumber
// Other properties removed for brevity
}
// From SwitchCellType.swift -- NOTE: Imports from Foundation and CoreData
@objc(SwitchCellType)
class SwitchCellType: CellType {
@NSManaged var targetCellXIndex: NSNumber
@NSManaged var targetCellYIndex: NSNumber
@NSManaged var targetCellType: CellType
// Other properties removed for brevity
}
// From CellTypeLogic.swift -- NOTE: Imports from Foundation and CoreData
extension CellType
{
var typeLabel : String { get { return "Empty"; } }
func isEqualToType(otherCellType : CellType) -> Bool
{
return (self.typeLabel == otherCellType.typeLabel &&
self.maxUses.isEqualToNumber(otherCellType.maxUses) &&
self.useCount.isEqualToNumber(otherCellType.useCount));
}
// Code removed for brevity
}
// From SwitchCellTypeLogic.swift -- NOTE: Imports from Foundation and CoreData
extension SwitchCellType // YES, this compiles with the overrides!
{
override var typeLabel : String { get { return "Switch"; } }
override func isEqualToType(otherCellType : CellType) -> Bool
{
var answer = false;
if let otherSwitchCellType = otherCellType as? SwitchCellType
{
answer = super.isEqualToType(otherCellType) &&
self.targetCellXIndex.isEqualToNumber(otherSwitchCellType.targetCellXIndex) &&
self.targetCellYIndex.isEqualToNumber(otherSwitchCellType.targetCellYIndex) &&
self.targetCellType.isEqualToType(otherSwitchCellType.targetCellType);
}
return answer;
}
// Code removed for brevity
}
Umarım bir tür Swift uzmanı zaten benim sorunumu görüyor, ancak işte bu konuyla ilgili nasıl öğrendim: Son zamanlarda, türlerde yerleşik olmayan parametreler ve/veya dönüş değerleri olan yöntemleri kullanarak benzer işlevleri eklemeyi denedim, ancak Bu hatayı almaya başladım: Uzantılardaki bildirimler henüz geçersiz sayılmaz.
Bu sorunu araştırmak için ben gayet güzel derlemek istiyorsunuz düşünmek benim hızlı dosyalardan biri için aşağıdaki eklendi: Benim için sürpriz
class A
{
}
class B : A
{
}
extension A
{
var y : String { get { return "YinA"; } }
}
extension B
{
override var y : String { get { return "YinB"; } } // Compiler error (see below) -- What??
}
, ben aynı derleyici hatası aldı (uzantılarında Beyannameler henüz geçersiz kılamaz). Ne? Ama ben bu derleyiciyi derleyici hataları olmadan birkaç kez kullandım.
Sorular: İlk olarak, bazı durumlarda çalışmasının gerektiği, ancak diğer durumlarda değil, uzantıların geçersiz kılınmasıyla ilgili bazı kurallar var mıdır? İkincisi (ve daha da rahatsız edici), neden Swift derleyicisinin bu kadar tutarsız olduğu görünüyor? Burada neyi özlüyorum? Swift'e olan inancımı geri kazanmama yardım edin.
GÜNCELLEME: Martin R tarafından doğru cevap belirtildiği gibi
, sürece (1) yalnızca sınıfları dahil olarak (Xcode 6.1 üzerinden 1.1) Swift geçerli sürümünde yöntemlerini geçersiz kılabilir görünüyor NSObject türetilmiştir ve (2) inout değiştirici kullanmayın. İşte bazı örnekler verilmiştir:
class A : NSObject { }
class B : A { }
class SubNSObject : NSObject {}
class NotSubbed {}
enum SomeEnum { case c1, c2; }
extension A
{
var y : String { get { return "YinA"; } }
func f() -> A { return A(); }
func g(val: SubNSObject, test: Bool = false) { }
func h(val: NotSubbed, test: Bool = false) { }
func j(val: SomeEnum) { }
func k(val: SubNSObject, inout test: Bool) { }
}
extension B
{
// THESE OVERIDES DO COMPILE:
override var y : String { get { return "YinB"; } }
override func f() -> A { return A(); }
override func g(val: SubNSObject, test: Bool) { }
// THESE OVERIDES DO NOT COMPILE:
//override func h(val: NotSubbed, test: Bool = false) { }
//override func j(val: SomeEnum) { }
//override func k(val: SubNSObject, inout test: Bool) { }
}
Doğru cevap bu gibi görünüyor. Ayrıca, inout'u kullanan yöntemleri geçersiz kılabilirsiniz. Bunu kendim kontrol ettim ve bazı basit örnekler vermek için soruma bir güncelleme ekleyeceğim. Teşekkürler! – FTLPhysicsGuy
@FTLPhysicsGuy: Haklısın ve cevabım eksikti. Gerçek ölçüt, yöntemin veya özelliklerin Objektif-C uyumlu olup olmadığıdır. Cevabını buna göre güncelledim. –
Aynı sorunu xCode 7.2 kullanarak aldım. Mesajda "uzantılardaki bildirimlerin henüz geçersiz kılınamayacağını" söylüyor. Bu benim için çok büyük bir problem, çünkü UICollectionViewCell ve UICollectionReusableView için hem alt sınıflarında daha sonra geçersiz kılınabilecek bazı yöntemleri kullanmak istiyorum. – Darius