我有一个聊天 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/