func (cls object) className() string {
	return C.GoString(C.GoObjc_GetClassName(unsafe.Pointer(cls.Pointer())))
}
className returns the name of the Class represented by object.
package objc
import "C"
import (
	"reflect"
	"strings"
	"unsafe"
)
type classInfo struct {
	typ       reflect.Type
	methodMap map[string]interface{}
	refs      map[uintptr]unsafe.Pointer
	setters   map[string]struct{}
}
func (ci classInfo) MethodForSelector(sel string) interface{} {
	return ci.methodMap[sel]
}
func (ci *classInfo) AddRef(ptr unsafe.Pointer) {
	if ci.refs == nil {
		ci.refs = make(map[uintptr]unsafe.Pointer)
	}
	ci.refs[uintptr(ptr)] = ptr
}
func (ci *classInfo) RemoveRef(ptr unsafe.Pointer) {
	if ci.refs != nil {
		delete(ci.refs, uintptr(ptr))
	}
}
var (
	classMap map[string]classInfo
)
func init() {
	classMap = make(map[string]classInfo)
}
type Class interface {
	Object
	AddMethod(selector string, fn interface{})
}
func NewClass(value interface{}) Class {
	typ := reflect.ValueOf(value).Type()
	field := typ.Field(0)
	descrStr := field.Tag.Get("objc")
	descr := strings.Split(descrStr, " : ")
	if len(descr) != 2 {
		panic("objc: bad description string for class " + typ.Name())
	}
	className := descr[0]
	superClassName := descr[1]
	superClass := GetClass(superClassName)
	ptr := C.GoObjc_AllocateClassPair(unsafe.Pointer(superClass.Pointer()), C.CString(className))
	if ptr == nil {
		panic("unable to AllocateClassPair")
	}
	setters := map[string]struct{}{}
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		if field.Tag.Get("objc") == "IBOutlet" {
			if field.Type.Implements(objectInterfaceType) {
				setters["set"+field.Name+":"] = struct{}{}
				break
			} else {
				panic("IBOutlets must implement objc.Object")
			}
		}
	}
	for setterSelector, _ := range setters {
		sel := selectorWithName(setterSelector)
		typeInfo := encVoid + encId + encSelector + encId
		C.GoObjc_ClassAddMethod(ptr, sel, methodCallTarget(), C.CString(typeInfo))
	}
	if len(setters) > 0 {
		sel := selectorWithName("setValue:forKey:")
		typeInfo := encVoid + encId + encSelector + encId + encId
		C.GoObjc_ClassAddMethod(ptr, sel, methodCallTarget(), C.CString(typeInfo))
	}
	sel := selectorWithName("dealloc")
	typeInfo := encVoid + encId + encSelector
	C.GoObjc_ClassAddMethod(ptr, sel, methodCallTarget(), C.CString(typeInfo))
	classMap[className] = classInfo{
		typ:       reflect.TypeOf(value),
		methodMap: make(map[string]interface{}),
		setters:   setters,
	}
	return object{ptr: uintptr(ptr)}
}
func GetClass(name string) Class {
	return object{ptr: uintptr(C.GoObjc_GetClassByName(C.CString(name)))}
}
func getObjectClass(obj Object) Class {
	classPtr := C.GoObjc_GetObjectClass(unsafe.Pointer(obj.Pointer()))
	return object{ptr: uintptr(classPtr)}
}
func RegisterClass(class Class) {
	C.GoObjc_RegisterClass(unsafe.Pointer(class.Pointer()))
}