“没有更多上下文,表达的类型是模糊的”

时间:2016-03-27 19:00:10

标签: objective-c swift

我有一个带有WKInterfaceTable固定消息的聊天控制器,每个表行都是一种不同类型的rowController,在WatchKit中附带一个WKInterfaceTable。

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

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

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

我试图修剪尽可能多的代码,因为我知道SO喜欢这样。虽然在不同的函数中有一些引用,但我还包括了保持显式的所需内容。

的OBJ-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;
}
}

1 个答案:

答案 0 :(得分:1)

让我们分解一下:

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看起来像布尔值,我们为什么要为它分配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)
    }
}