objective-c - "Type of expression is ambiguous without more context"

标签 objective-c swift

我有一个聊天 Controller ,带有一个包含预设消息的 WKInterfaceTable,每个表行都是一种不同类型的 rowController,在 WatchKit 中带有 WKInterfaceTable。

每个 rowController 引用一个在枚举中定义的 MessageSource 和 MessageType。

我的枚举的声明看起来不错,但相关字典的实现语法需要一些帮助。

与相同 block 相关的另一个问题是我的属性的 Swift 转换。我不确定我是否正确声明了它们,因此它们可能会影响相同的 block 。

我尝试尽可能多地修剪代码,因为我知道我很喜欢这种方式。不过,不同的函数中有一些引用资料,因此我包含了保持内容明确所需的内容。

对象-C

Controller .m

typedef enum {
MessageSourceIncoming = 1,
MessageSourceOutgoing = 2
} MessageSource;

typedef enum {
MessageTypeText = 1,
MessageTypeVoice = 2,
MessageTypeImage = 3
} MessageType;

- (void)setupTable {
_messages = [NSMutableArray array];
for (int i = 0; i < rand()%20; i++) {
    [_messages addObject:@{@"msg":@[@"Hi", @"OK", @"Nice to meet you", @"Fine"][rand()%4], @"source":@(rand()%2), @"type":@(rand()%3)}];
}

// clear the table rows
[_table removeRowsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, _table.numberOfRows)]];
for (int i = 0; i < _messages.count; i++) {
    NSDictionary *messageDic = _messages[i];
    [self insertRowForMessage:messageDic];
}
}

- (void)willActivate {
[_table scrollToRowAtIndex:_table.numberOfRows - 1];
if (_shouldSendVoice) {
    NSDictionary *messageDic = @{@"source":@(MessageSourceOutgoing), @"type":@(MessageTypeVoice), @"path":_shouldSendVoice};
    [_messages addObject:messageDic];
    [self insertRowForMessage:messageDic];
    _shouldSendVoice = nil;
}
}

最佳答案

让我们分解一下:

enum MessageSource: Int {
   case MessageSourceIncoming = 1
   case MessageSourceOutgoing = 2
}

enum MessageType: Int {
   case MessageTypeText = 1
   case MessageTypeVoice = 2
   case MessageTypeImage = 3
}

枚举没有任何问题,但是是否需要为它们提供整数值是一个问题。不过,您不必分配每个值:

enum MessageType: Int {
   case MessageTypeText = 1
   case MessageTypeVoice
   case MessageTypeImage
}

可以正常工作,并且值是相同的。

var chat = NSDictionary()
var messages = NSMutableArray()
var shouldSendVoice = NSString()

chat 可能应该是一个 Swift 字典,但我们没有足够的信息来设置类型,所以我将跳过它。 shouldSendVoice 看起来像一个 bool 值,为什么我们要给它分配一个 NSString 呢?我不确定你如何使用它,所以我不会重命名它,但让我们从中创建一个可选字符串。 messages 应该是一个 Swift 数组。让我们为 Message 创建一个类型:

struct Message {
    let message: String?
    let source: MessageSource
    let type: MessageType
    let path: String?
}

var chat = NSDictionary() // let's ignore this
var messages: [Message] = []  // empty swift array of messages
var shouldSendVoice: String? = nil // optional String

现在,让我们重写其余部分:

override func willActivate() {
    super.willActivate()

    self.table.scrollToRowAtIndex(table.numberOfRows - 1)

    // in Obj-C this was checking for nil!, we have to check explicitly in Swift
    if let shouldSendVoice = self.shouldSendVoice {
        // let's not use Dictionaries for custom objects
        let message = Message(message: nil, source: .MessageSourceIncoming, type: .MessageTypeVoice, path: shouldSendVoice)
        self.messages.append(message)

        self.insertRowForMessage(message) 
        // I think you don't want new String here, just `nil`
        shouldSendVoice = nil
    }
}

func setupTable() {
    // let's use a saner way to generate randoms
    let numMessages = Int(arc4random_uniform(20))

    self.messages = (0..<numMessages).map { _ in
       let message = // randomize the message
       let source = // randomize source
       let type = // randomize type

       return Message(message: message, source: source, type: type, path: nil)
    }

    // let's split multiple operations into separate lines to make code more readable
    let indicesToRemove = NSIndexSet(indexesInRange:NSMakeRange(0, table.numberOfRows))
    self.table.removeRowsAtIndexes(indicesToRemove)

    // let's use for-in without using an index
    for message in messages {
        self.insertRowForMessage(message)
    }
}

关于objective-c - "Type of expression is ambiguous without more context",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36251339/

相关文章:

ios - Swift:如何编写采用可选序列类型的枚举变体

swift - Google Auth 登录对成员 'subscript' 的引用不明确

c++ - 从数组中获取字节值并合并它们。

ios - 执行多个sqlite3_exec,不创建表,为什么?

ios - 文本字段中的边框和填充样式不适用于 swift5

swift - UITextfield 在 UICollectionView reloadData() 之后成为FirstResponder

ios - swift3 字典限制命令因信号 : Segmentation fault: 11 而失败

objective-c - 集合 <__NSArrayM : 0x76c11b0> was mutated while being enumerated

ios - 为什么导航 View Controller 返回零 View Controller ?

objective-c - 为什么当在 UITextField 中点击清除按钮时,应用程序仅在 iOS 10 上挂起?