简体   繁体   English

在Swift 3的值类型中访问Objective-C类别的属性(相关引用)

[英]Access Objective-C Category's Property (Associated Reference) in Swift 3's Value Type

In my Objective-C class's .h file, I have created a Category for NSIndexPath like this: 在我的Objective-C类的.h文件中,我为NSIndexPath创建了一个Category,如下所示:

@interface NSIndexPath (YVTableView)

@property (nonatomic, assign) NSInteger subRow;

@end

and in that class's .m file, I have implemented that like: 在该类的.m文件中,我已实现了以下内容:

static void *SubRowObjectKey;

@implementation NSIndexPath (YVTableView)

@dynamic subRow;

- (NSInteger)subRow
{
    id subRowObj = objc_getAssociatedObject(self, SubRowObjectKey);
    return [subRowObj integerValue];
}

- (void)setSubRow:(NSInteger)subRow
{
    id subRowObj = [NSNumber numberWithInteger:subRow];
    objc_setAssociatedObject(self, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

Now, when I am accessing the subRow property of NSIndexPath in Swift 3 using IndexPath then its giving me error: 现在,当我使用IndexPath访问Swift 3中NSIndexPath的subRow属性时,它给了我错误:

Value of type 'IndexPath' has no member 'subRow' 类型“ IndexPath”的值没有成员“ subRow”

If I am trying to access it using type casting 如果我尝试使用类型转换访问它

let subIndexPath = indexPath as NSIndexPath
let subRowIndex = subIndexPath.subRow

its always returning me '0' as 'subRow' value. 它总是返回“ 0”作为“ subRow”值。 May be its because IndexPath is value type and NSIndexPath is reference type. 可能是因为IndexPath是值类型,而NSIndexPath是引用类型。

I have implemented UITableViewDelegate to my Custom Delegate using Objective-C and implemented it to Swift class but in Swift where I am implementing the Custom Delegate methods, I am facing this issue. 我已经使用Objective-C将UITableViewDelegate实现到我的自定义委托并将其实现到Swift类,但是在我要实现Custom Delegate方法的Swift中,我遇到了这个问题。

I also tried to use NSIndexPath instead of IndexPath in my Custom Delegate implementation (Swift code) but it was giving me the error "Type YVViewController does not conform to protocol, Candidate has non matching-type". 我还尝试在自定义委托实现(Swift代码)中使用NSIndexPath而不是IndexPath,但是它给我错误“类型YVViewController不符合协议,候选对象具有非匹配类型”。

Here is my Custom Delegate declaration : 这是我的自定义委托声明:

@protocol YVTableViewDelegate <UITableViewDelegate>

@required

- (UITableViewCell *)tableView:(SKSTableView *)tableView cellForSubRowAtIndexPath:(NSIndexPath *)indexPath;

@end

Its working perfectly fine with Swift 2.x but after migrating to Swift 3, I am facing this issue. 它可以与Swift 2.x完美配合,但是在迁移到Swift 3之后,我面临着这个问题。

The subRow associated with an NSIndexPath will not be associated with an IndexPath casted from that NSIndexPath because they are not the same "object". subRow与相关的NSIndexPath不会与关联IndexPath从铸造NSIndexPath ,因为他们是不一样的“对象”。 IndexPath is a value type in Swift, defined with the struct keyword, so it cannot have an Objective-C associated object. IndexPath是Swift中的一种值类型,使用struct关键字定义,因此它不能具有与Objective-C关联的对象。

So even if you have set a value to subRow of an NSIndexPath in Objective-C code, the value is lost when that NSIndexPath is casted to Swift's IndexPath . 因此,即使您在Objective-C代码中为NSIndexPath subRow设置了一个值,当将该NSIndexPath IndexPath为Swift的IndexPath时,该值也会丢失。 That's why when you again cast the IndexPath back to NSIndexPath , the subRow value is always 0, which is the default value. 因此,当您再次将IndexPathNSIndexPathsubRow值始终为0,这是默认值。

In your case, you need to declare the protocol in Swift and specify the index path parameter type as NSIndexPath . 在您的情况下,您需要在Swift中声明协议,并将索引路径参数类型指定为NSIndexPath

func tableView(_ tableView: SKSTableView, cellForSubRowAt indexPath: NSIndexPath) -> UITableViewCell

You can however update your category as follows:- 但是,您可以按以下方式更新类别:

- (NSInteger)subRow
{

    id myclass = [SKSTableView class];
  //  id subRowObj = objc_getAssociatedObject(self, SubRowObjectKey);
    id subRowObj = objc_getAssociatedObject(myclass, SubRowObjectKey);
    return [subRowObj integerValue];
}

- (void)setSubRow:(NSInteger)subRow
{
    id subRowObj = [NSNumber numberWithInteger:subRow];

    id myclass = [SKSTableView class];
   // objc_setAssociatedObject(self, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    objc_setAssociatedObject(myclass, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM